├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── docs ├── CNAME ├── _global │ ├── .gitignore │ ├── css │ │ ├── global-syntax-highlight.css │ │ └── global.css │ ├── hooks │ │ ├── inline_pre_to_code_fence.py │ │ └── merge_inherited_config.py │ ├── js │ │ └── global.js │ ├── mkdocs.yml │ ├── overrides │ │ ├── 404.html │ │ ├── main.html │ │ ├── partials │ │ │ ├── copyright.html │ │ │ └── toc-item.html │ │ └── templates │ │ │ ├── print_site_banner.tpl │ │ │ └── print_site_cover_page.tpl │ ├── readme.md │ ├── requirements.txt │ └── scripts │ │ └── update-common-components.py ├── _static │ ├── AE_Log.png │ ├── Unlock.png │ ├── appleclang-symbols.png │ ├── debugmonitor.png │ ├── extra.css │ └── mac_universal_build.png ├── aegps │ ├── aegp-details.md │ ├── aegp-suites.md │ ├── aegps.md │ ├── cheating-effect-usage-of-aegp-suites.md │ ├── data-types.md │ ├── implementation.md │ └── overview.md ├── aeios │ ├── AEIO_ModuleInfo.md │ ├── aeios.md │ ├── calling-sequence.md │ ├── implementation-details.md │ └── new-kids-on-the-function-block.md ├── artisans │ ├── artisan-data-types.md │ └── artisans.md ├── audio │ ├── accessing-audio-data.md │ ├── audio-considerations.md │ ├── audio-data-structures.md │ ├── audio-specific-float-slider-variables.md │ ├── audio.md │ └── global-outflags.md ├── effect-basics │ ├── PF_EffectWorld.md │ ├── PF_InData.md │ ├── PF_OutData.md │ ├── PF_ParamDef.md │ ├── command-selectors.md │ ├── effect-basics.md │ ├── entry-point.md │ ├── errors.md │ └── parameters.md ├── effect-details │ ├── accessing-camera-light-information.md │ ├── accessing-function-suites.md │ ├── arbitrary-data-parameters.md │ ├── changing-parameter-orders.md │ ├── color-space-conversion.md │ ├── compute-cache-api.md │ ├── effect-details.md │ ├── global-sequence-frame-data.md │ ├── graphics-utility-suites.md │ ├── image-buffer-management-functions.md │ ├── interaction-callback-functions.md │ ├── iteration-suites.md │ ├── memory-allocation.md │ ├── motion-blur.md │ ├── multi-frame-rendering-in-ae.md │ ├── parameter-supervision.md │ ├── parameters-floating-point-values.md │ ├── pixel-aspect-ratio.md │ ├── tips-tricks.md │ ├── useful-utility-functions.md │ └── working-with-paths.md ├── effect-ui-events │ ├── PF_EventExtra.md │ ├── PF_EventUnion.md │ ├── custom-ui-and-drawbot.md │ ├── effect-ui-events.md │ ├── tips-and-tricks.md │ └── ui-callbacks.md ├── history.md ├── index.md ├── intro │ ├── apple-silicon-support.md │ ├── compatibility-across-multiple-versions.md │ ├── debugging-plug-ins.md │ ├── exceptions.md │ ├── how-to-start-creating-plug-ins.md │ ├── localization.md │ ├── next-steps.md │ ├── other-integration-possibilities.md │ ├── pipl-resources.md │ ├── sample-projects.md │ ├── sdk-audience.md │ ├── symbol-export.md │ ├── third-party-plug-in-hosts.md │ ├── what-can-i-do.md │ ├── whats-new.md │ └── where-installers-should-put-plug-ins.md ├── ppro │ ├── basic-host-differences.md │ ├── bigger-differences.md │ ├── multithreading.md │ ├── other-hosts.md │ ├── plug-in-installation.md │ ├── plug-ins-reloaded.md │ ├── ppro.md │ ├── premiere-elements.md │ └── unsupported-features.md └── smartfx │ └── smartfx.md ├── mkdocs.yml ├── readme.md └── requirements.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Override linguist skipping main folder 2 | docs/** -linguist-documentation 3 | docs/** linguist-detectable 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - main 8 | permissions: 9 | contents: write 10 | jobs: 11 | deploy: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | - name: Configure Git Credentials 18 | run: | 19 | git config user.name github-actions[bot] 20 | git config user.email 41898282+github-actions[bot]@users.noreply.github.com 21 | 22 | - uses: actions/setup-python@v5 23 | with: 24 | python-version: 3.x 25 | 26 | - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV 27 | 28 | - uses: actions/cache@v4 29 | with: 30 | key: mkdocs-material-${{ env.cache_id }} 31 | path: .cache 32 | restore-keys: | 33 | mkdocs-material- 34 | 35 | - name: Install Python dependencies 36 | uses: py-actions/py-dependency-install@v4 37 | 38 | - run: mkdocs gh-deploy --force 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-project 2 | *.sublime-workspace 3 | .DS_Store 4 | .vscode/ 5 | __pycache__/ 6 | site/ 7 | venv/ 8 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | ae-plugins.docsforadobe.dev 2 | -------------------------------------------------------------------------------- /docs/_global/.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-project 2 | *.sublime-workspace 3 | .DS_Store 4 | .vscode/ 5 | __pycache__/ 6 | site/ 7 | venv/ 8 | -------------------------------------------------------------------------------- /docs/_global/css/global-syntax-highlight.css: -------------------------------------------------------------------------------- 1 | /* Set light & dark mode syntax highlight */ 2 | 3 | @media screen { 4 | /* Light mode */ 5 | [data-md-color-scheme="default"] { 6 | --md-code-fg-color: #36464e; 7 | --md-code-bg-color: #f5f5f5; 8 | --md-code-hl-color: #4287ff; 9 | 10 | --md-code-hl-constant-color: #6e59d9; 11 | --md-code-hl-function-color: #a846b9; 12 | --md-code-hl-keyword-color: #3f6ec6; 13 | --md-code-hl-number-color: #d52a2a; 14 | --md-code-hl-special-color: #db1457; 15 | --md-code-hl-string-color: #1c7d4d; 16 | --md-code-hl-comment-color: var(--md-default-fg-color--light); 17 | --md-code-hl-generic-color: var(--md-default-fg-color--light); 18 | --md-code-hl-name-color: var(--md-code-fg-color); 19 | --md-code-hl-operator-color: var(--md-default-fg-color--light); 20 | --md-code-hl-punctuation-color: var(--md-default-fg-color--light); 21 | --md-code-hl-variable-color: var(--md-default-fg-color--light); 22 | } 23 | 24 | /* Dark mode */ 25 | [data-md-color-scheme="slate"] { 26 | --md-code-bg-color: #272a35; 27 | --md-code-fg-color: #d5d8e2d1; 28 | --md-code-hl-color: #2977ff; 29 | 30 | --md-code-hl-constant-color: #9383e2; 31 | --md-code-hl-function-color: #c973d9; 32 | --md-code-hl-keyword-color: #6791e0; 33 | --md-code-hl-number-color: #e6695b; 34 | --md-code-hl-special-color: #f06090; 35 | --md-code-hl-string-color: #2fb170; 36 | --md-code-hl-comment-color: var(--md-default-fg-color--light); 37 | --md-code-hl-generic-color: var(--md-default-fg-color--light); 38 | --md-code-hl-name-color: var(--md-code-fg-color); 39 | --md-code-hl-operator-color: var(--md-default-fg-color--light); 40 | --md-code-hl-punctuation-color: var(--md-default-fg-color--light); 41 | --md-code-hl-variable-color: var(--md-default-fg-color--light); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/_global/css/global.css: -------------------------------------------------------------------------------- 1 | /* 2 | Fix issue with 'code' text in tables wrapping to multiple lines 3 | Excludes any preformatted code blocks within tables 4 | */ 5 | td code:not(.md-code__content) { 6 | white-space: nowrap; 7 | } 8 | -------------------------------------------------------------------------------- /docs/_global/hooks/inline_pre_to_code_fence.py: -------------------------------------------------------------------------------- 1 | # Converts inline
code
blocks to pygments-highlighted html
2 | # Custom hook to highlight and format codecode
blocks
3 | #
4 | # This is used for blocks embedded in tables, as these otherwise are skipped by pygments
5 | #
6 | # Note: It's possible this can be done better with Python-markdown inline patterns (https://python-markdown.github.io/reference/markdown/inlinepatterns),
7 | # but the below works For Now
8 |
9 | import re
10 | import markdown
11 |
12 | import mkdocs
13 | from mkdocs.structure.pages import Page
14 | from mkdocs.config.defaults import MkDocsConfig
15 | from mkdocs.structure.files import Files
16 |
17 | from pymdownx.highlight import HighlightExtension
18 |
19 | # Get current mkdocs config
20 | user_extensions = MkDocsConfig.markdown_extensions.__dict__.get('configdata');
21 | highlight_config = dict()
22 |
23 | if 'pymdownx.highlight' in user_extensions:
24 | highlight_config = user_extensions.get('pymdownx.highlight')
25 |
26 | ExistingHighlighter = HighlightExtension().get_pymdownx_highlighter()(**highlight_config)
27 |
28 | def on_page_content(html: str, page: Page, config: MkDocsConfig, files: Files, **kwargs):
29 | def inline_pre_to_code_fence(match):
30 | raw = match.group()
31 |
32 | ## Check for language
33 | lang = ''
34 | langmatch = re.search('lang="(.*?)"', raw)
35 |
36 | if langmatch:
37 | lang = langmatch.group(1)
38 |
39 | ## Remove first tag
40 | pre = re.sub('', '', raw)
41 |
42 | ## Strip end tag
43 | pre = re.sub('
', '', pre)
44 |
45 | ## Swap html linebreaks
46 | pre = re.sub('(.+)
', inline_pre_to_code_fence, html)
51 |
52 | return result
53 |
--------------------------------------------------------------------------------
/docs/_global/hooks/merge_inherited_config.py:
--------------------------------------------------------------------------------
1 | # Handles merging mkdocs config in a way the native inheritance feature doesn't quite cover
2 | #
3 | # This relies on a key in "extra.overrides"
4 | # Valid keys are `custom_dir: str` and `hooks: [-path/to.py, -path/to.py]`, e.g.
5 | #
6 | # ```yml
7 | # extra:
8 | # overrides:
9 | # custom_dir: overrides
10 | # extra_css:
11 | # - docs/_global/css/global.css
12 | # - docs/_global/css/global-syntax-highlight.css
13 | # extra_javascript:
14 | # - docs/_global/js/global.js
15 | # hooks:
16 | # - hooks/local_override.py
17 | # - hooks/local_override2.py
18 | # not_in_nav:
19 | # - gitignore_style/path/to/exclude
20 | # theme_features:
21 | # - theme.feature1
22 | # - theme.feature2
23 | # ```
24 |
25 | import os
26 |
27 | from pathspec.gitignore import GitIgnoreSpec
28 |
29 | import mkdocs
30 | from mkdocs.config.defaults import MkDocsConfig
31 | from mkdocs.config.config_options import (File, FilesystemObject, Hooks, ListOfItems, PathSpec)
32 | from mkdocs.structure.files import (File as FileStructure, Files)
33 |
34 | # Load any local files into mkdocs
35 | def append_local_files(files: Files, config: MkDocsConfig, local_files: list[str]):
36 | for local_file_path in local_files:
37 | local_file = FileStructure(
38 | path= local_file_path,
39 | src_dir=config["docs_dir"] + "/../",
40 | dest_dir=config["site_dir"],
41 | use_directory_urls=False,
42 | )
43 |
44 | files.append(local_file)
45 |
46 | # Load any override hooks
47 | def merge_local_hooks(config: MkDocsConfig, hooks: list[str]):
48 | try:
49 | paths = ListOfItems(File(exists=True)).validate(hooks)
50 | except Exception as e:
51 | raise e
52 |
53 | for name, path in zip(hooks, paths):
54 | config.plugins[name] = Hooks._load_hook(mkdocs, name, path)
55 |
56 | # Handle multiple "not in nav" entries
57 | # These are of a pathspec.gitignore.GitIgnoreSpec format and need to be converted to a multiline string
58 | def merge_local_not_in_nav(config: MkDocsConfig, not_in_nav: list[GitIgnoreSpec]):
59 | nav_str = "\n".join(not_in_nav)
60 | config["not_in_nav"] += PathSpec().run_validation(nav_str)
61 |
62 | # Add additional theme_override folder
63 | def merge_local_theme_override(config: MkDocsConfig, custom_dir: str):
64 | try:
65 | local_override_path = FilesystemObject(exists=True).validate(custom_dir)
66 | except Exception as e:
67 | raise e
68 |
69 | config.theme.dirs.insert(1, local_override_path)
70 |
71 | # Load any override theme features
72 | def merge_local_theme_features(config: MkDocsConfig, theme_features: list[str]):
73 | for local_feature in theme_features:
74 | config.theme["features"].append(local_feature)
75 |
76 |
77 |
78 | ##### MkDocs Event Hooks
79 |
80 | def on_files(files: Files, config: MkDocsConfig):
81 | if "overrides" in config.extra:
82 | extra_overrides = config.extra["overrides"]
83 |
84 | if "extra_css" in extra_overrides:
85 | extra_css = extra_overrides["extra_css"]
86 | append_local_files(files, config, extra_css)
87 |
88 | if "extra_javascript" in extra_overrides:
89 | extra_javascript = extra_overrides["extra_javascript"]
90 | append_local_files(files, config, extra_javascript)
91 |
92 | def on_config(config: MkDocsConfig):
93 | if "overrides" in config.extra:
94 | extra_overrides = config.extra["overrides"]
95 |
96 | # Keep Hooks first
97 | if "hooks" in extra_overrides:
98 | hooks = extra_overrides["hooks"]
99 | merge_local_hooks(config, hooks)
100 |
101 | if "custom_dir" in extra_overrides:
102 | custom_dir = extra_overrides["custom_dir"]
103 | merge_local_theme_override(config, custom_dir)
104 |
105 | if "extra_css" in extra_overrides:
106 | extra_css = extra_overrides["extra_css"]
107 | config.extra_css.extend(extra_css)
108 |
109 | if "extra_javascript" in extra_overrides:
110 | extra_javascript = extra_overrides["extra_javascript"]
111 | config.extra_javascript.extend(extra_javascript)
112 |
113 | if "not_in_nav" in extra_overrides:
114 | not_in_nav = extra_overrides["not_in_nav"]
115 | merge_local_not_in_nav(config, not_in_nav)
116 |
117 | if "theme_features" in extra_overrides:
118 | theme_features = extra_overrides["theme_features"]
119 | merge_local_theme_features(config, theme_features)
120 |
--------------------------------------------------------------------------------
/docs/_global/js/global.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docsforadobe/after-effects-plugin-guide/57465fc7f03463ad2c714b82d570c6c0d067646a/docs/_global/js/global.js
--------------------------------------------------------------------------------
/docs/_global/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Shared config for all repos
2 | copyright: All content is copyright Adobe Systems Incorporated.
3 |
4 | extra:
5 | homepage: https://docsforadobe.dev
6 |
7 | # Using overrides here as we can't inherit "extra_css"
8 | overrides:
9 | extra_css:
10 | - docs/_global/css/global.css
11 | - docs/_global/css/global-syntax-highlight.css
12 | extra_javascript:
13 | - docs/_global/js/global.js
14 |
15 | hooks:
16 | - docs/_global/hooks/inline_pre_to_code_fence.py
17 | - docs/_global/hooks/merge_inherited_config.py
18 |
19 | markdown_extensions:
20 | admonition: {}
21 | markdown_grid_tables: {}
22 | md_in_html: {}
23 | pymdownx.details: {}
24 | pymdownx.highlight:
25 | line_spans: __span
26 | pygments_lang_class: true
27 | pymdownx.superfences: {}
28 | pymdownx.tabbed:
29 | alternate_style: true
30 | pymdownx.tasklist:
31 | custom_checkbox: true
32 | toc:
33 | title: Page Contents
34 | permalink: true
35 | toc_depth: 3
36 |
37 | not_in_nav: |
38 | _global
39 |
40 | plugins:
41 | git-revision-date-localized: {}
42 | search:
43 | separator: '[\s\-,\.:!=\[\]()"/]+'
44 |
45 | # Note: print-site must be last!
46 | print-site:
47 | add_cover_page: true
48 | add_print_site_banner: true
49 | cover_page_template: "docs/_global/overrides/templates/print_site_cover_page.tpl"
50 | print_page_title: "Offline Docs"
51 | print_site_banner_template: "docs/_global/overrides/templates/print_site_banner.tpl"
52 |
53 | theme:
54 | name: material
55 | custom_dir: docs/_global/overrides
56 | features:
57 | - announce.dismiss
58 | - content.action.edit
59 | - content.action.view
60 | - content.code.copy
61 | - search.highlight
62 | - search.suggest
63 | - toc.follow
64 | palette:
65 | # Palette toggle for dark mode
66 | - media: "(prefers-color-scheme: dark)"
67 | primary: black
68 | scheme: slate
69 | toggle:
70 | icon: material/brightness-4
71 | name: Switch to light mode
72 |
73 | # Palette toggle for light mode
74 | - media: "(prefers-color-scheme: light)"
75 | primary: white
76 | scheme: default
77 | toggle:
78 | icon: material/brightness-7
79 | name: Switch to dark mode
80 |
--------------------------------------------------------------------------------
/docs/_global/overrides/404.html:
--------------------------------------------------------------------------------
1 | {% extends "main.html" %}
2 |
3 |
4 | {% block extrahead %}
5 |
10 | {% endblock %}
11 |
12 | {% block content %}
13 | Note – This box will disappear during export!
10 | 11 |This page has combined all site pages into one, and can be exported using native browser features.
12 | 13 |You can export to PDF using File > Print > Save as PDF, or save as a single-page HTML file via File > Save As.
14 | 15 |Warning
17 | 18 |Note that users may have issues printing to PDF on Firefox.
19 |Description | 19 |{{ config.site_description }} | 20 |
Hosted at | 26 |{{ config.site_url }} | 27 |
Repository | 33 |{{ config.repo_url }} | 34 |
Copyright | 40 |{{ config.copyright }} | 41 |
typedef struct {
A_u_char alpha, red, green, blue;
} PF_Pixel8;
|
12 | | 16 bpc ARGB | typedef struct {
A_u_short alpha, red, green, blue;
} PF_Pixel16;
|
13 | | 32 bpc ARGB | typedef struct {
PF_FpShort alpha, red, green, blue;
} PF_PixelFloat, PF_Pixel32;
|
14 | | HLS (Hue, Lightness, Saturation) | typedef PF_Fixed PF_HLS_PIXEL[3]
|
15 | | YIQ (luminance, in-phase chrominance, quadrature chrominance) | typedef PF_Fixed PF_YIQ_PIXEL[3]
|
16 |
17 | ---
18 |
19 | Plug-ins can draw on image processing algorithms written for nearly any color space by using the following callback functions.
20 |
21 | ## Color Space Conversion Callbacks
22 |
23 | | Function | Purpose | Replaces |
24 | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
25 | | RGBtoHLS | Given an RGB pixel, returns an HLS (hue, lightness, saturation) pixel. HLS values are scaled from 0 to 1 in fixed point. | `PF_RGB_TO_HLS` |
26 | | HLStoRGB | Given an HLS pixel, returns an RGB pixel. | `PF_HLS_TO_RGB` |
27 | | RGBtoYIQ | Given an RGB pixel, returns a YIQ (luminance, inphase chrominance, quadrature chrominance) pixel. Y is 0 to 1 in fixed point, I is -0.5959 to 0.5959 in fixed point, and Q is -0.5227 to 0.5227 in fixed point. | `PF_RGB_TO_YIQ` |
28 | | YIQtoRGB | Given a YIQ pixel, returns an RGB pixel. | `PF_YIQ_TO_RGB` |
29 | | Luminance | Given an RGB pixel, returns 100 times its luminance value (0 to 25500). | `PF_LUMINANCE` |
30 | | Hue | Given an RGB pixel, eturns its hue angle mapped from 0 to 255, where 0 is 0 degrees and 255 is 360 degrees. | `PF_HUE` |
31 | | Lightness | Given an RGB pixel, returns its lightness value (0 to 255). | `PF_LIGHTNESS` |
32 | | Saturation | Given an RGB pixel, returns its saturation value (0 to 255). | `PF_SATURATION` |
33 |
--------------------------------------------------------------------------------
/docs/effect-details/effect-details.md:
--------------------------------------------------------------------------------
1 | # Effect Details
2 |
3 | Now that we've covered the basics of effect plug-ins, we'll cover some of the finer points to polish off your effect. Not every section will be relevant to every plug-in, so feel free to use the PDF document bookmarks to skip to the sections pertinent to your current project.
4 |
5 | ---
6 |
7 | ## Free Code == Good
8 |
9 | After Effects provides effect plug-ins with as much information and supporting code as possible. Use our function suites and callbacks to obtain the value of parameters (including source footage) at different times. Use our memory allocation suite to avoid competing with the host for resources. Use our image processing suites to copy, fill, blend and convolve images, and convert between color spaces. Obtain information about the masks applied to a layer. ANSI emulation and math utility suites are also provided, as well as information about the application, user, serial number, and current drawing context.
10 |
11 | Previous versions of After Effects have provided functions for many common tasks. As we moved to support deeper color, these were moved to function suites. Use the newer function suites whenever possible; things will just be better.
12 |
13 | Using our function suites keeps your plug-in compact; you write and test less code. The functions are tested, optimized, and used by our own plug-ins. The functions are distributed to multiple processors and take advantage of available hardware acceleration.
14 |
15 | No, really, use the provided functions. Seriously.
16 |
--------------------------------------------------------------------------------
/docs/effect-details/global-sequence-frame-data.md:
--------------------------------------------------------------------------------
1 | # Global, Sequence, & Frame Data
2 |
3 | After Effects allows plug-ins to store data at three scopes: global, sequence, and frame. Consider carefully where you store information; choosing poorly can impact performance, or make your plug-in confusing to the user.
4 |
5 | Use global data for information common to all instances of the effect: static variables and data, bitmaps, pointers to other DLLs or external applications. If your effect supports Multi-Frame Rendering, any static or global variables must be free of race conditions (see [What does it mean for an effect to be thread-safe?](multi-frame-rendering-in-ae.md#what-does-it-mean-for-an-effect-to-be-thread-safe) for more information).
6 |
7 | Store anything specific to this instance of your plug-in (UI settings, text strings, and any custom data not stored in parameters) in Sequence Data or in the new [Compute Cache For Multi-Frame Rendering](multi-frame-rendering-in-ae.md#compute-cache-for-multi-frame-rendering).
8 |
9 | Frame data is used for information specific to rendering a given frame. This has fallen into disuse, as most machines are capable of loading an entire frame into memory at a time. Of course, your IMAX-generating users will still appreciate any optimizations you can make.
10 |
11 | ---
12 |
13 | ## Persistence
14 |
15 | After Effects saves sequence data in the project file, but not global or frame data. Pointers within sequence data which point to external data are, in all likelihood, invalid upon reopening the project, and must be re-connected. We call this process "flattening" and "unflattening" the sequence data.
16 |
17 | !!! note
18 | The Compute Cache does not store its contents to the project file. The data stored in the cache must be recreated during render.
19 |
20 | ---
21 |
22 | ## Validating Sequence Data
23 |
24 | Careful sequence data validation is important for effects that do simulation across time, where frame N is dependent on frame N-1, and you use a cache of calculated data in your sequence data. If a parameter is changed, certain calculated data may no longer be valid, but it would also be wasteful to blindly recalculate everything after every change.
25 |
26 | When asked to render frame N, assuming you have your cached data calculated up to frame N-1, call `PF_GetCurrentState()` / `PF_AreStatesIdentical()` from [PF_ParamUtilSuite3](parameter-supervision.md#pf_paramutilsuite3) to see if the cache of calculated data is still valid given the current parameter settings.
27 |
28 | The state of all parameters (except those with [PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED](../effect-basics/PF_ParamDef.md#parameter-flags) set), including layer parameters (including [param[0]](../effect-basics/PF_ParamDef.md#param-zero)) are checked over the passed time span.
29 |
30 | This is done efficiently, as the change tracking is done with timestamps.
31 |
32 | If the inputs have not changed, you can safely use your cache, AND the internal caching system will assume that you have a temporal dependency on the passed range. So if something changes upstream, the host's caches will be properly invalidated automatically.
33 |
34 | To test that it is working, apply your effect with one parameter keyframed on every frame. RAM Preview to fill the cache, then change one of the keyframes. The related frame and all dependent frames (e.g. later frames, in the case of a simulation) should lose their cache marks and require re-rendering. Similarly, upstream changes to sources of layer parameters should cause time-selective invalidation of the cache.
35 |
36 | ---
37 |
38 | ## Flattened And Unflattened Sequence Data
39 |
40 | If your sequence data references external memory (in pointers or handles), you must flatten and unflatten your data for disk-safe storage. This is analogous to creating your own miniature file format.
41 |
42 | Upon receiving [PF_Cmd_SEQUENCE_FLATTEN](../effect-basics/command-selectors.md#sequence-selectors), put data referenced by pointers into one contiguous block from which you can later recover the old structure.
43 |
44 | If your sequence data contains a pointer to a long, allocate 4 bytes in which to store the flattened data. You must handle platform-specific byte ordering.
45 |
46 | Remember, your users (the ones who bought two copies of your plug-in, anyway) may want the same project to work on macOS and Windows.
47 |
48 | After Effects sends [PF_Cmd_SEQUENCE_RESETUP](../effect-basics/command-selectors.md#sequence-selectors) when the data is reloaded, for either flat or unflat data.
49 |
50 | Use a flag at a common offset within both structures to indicate the data's state.
51 |
52 | ```cpp
53 | typedef struct {
54 | A_char* messageZ;
55 | PF_FpLong big_numF;
56 | void* temp_storage;
57 | } non_flat_data;
58 |
59 | typedef struct {
60 | char message[256];
61 | PF_FpLong big_numF;
62 | A_Boolean big_endianB;
63 | } flat_data;
64 | ```
65 |
66 | ---
67 |
68 | ## Resizing Sequence Data
69 |
70 | During [PF_Cmd_SEQUENCE_SETUP](../effect-basics/command-selectors.md#sequence-selectors), allocate a handle for data specific to this instance of your effect.
71 |
72 | You may modify the contents, but not the size, of the sequence data during any selector.
73 |
74 | You may resize the sequence data handle only during the following selectors:
75 |
76 | - `PF_Cmd_AUDIO_SETUP`
77 | - `PF_Cmd_AUDIO_SETDOWN`
78 | - `PF_Cmd_FRAME_SETUP`
79 | - `PF_Cmd_FRAME_SETDOWN`
80 | - `PF_Cmd_AUDIO_RENDER`
81 | - `PF_Cmd_RENDER`
82 | - `PF_Cmd_SEQUENCE_SETUP`
83 | - `PF_Cmd_SEQUENCE_SETDOWN`
84 | - `PF_Cmd_SEQUENCE_FLATTEN`
85 | - `PF_Cmd_SEQUENCE_RESETUP`
86 | - `PF_Cmd_DO_DIALOG`
87 |
88 | ---
89 |
90 | ## Accessing sequence_data at Render Time with Multi-Frame Rendering
91 |
92 | When enabling Multi-Frame Rendering on an effect, the `sequence_data` object will be read-only/const during Render and accessible on each render thread via the `PF_EffectSequenceDataSuite1` suite.
93 |
94 | ### PF_EffectSequenceDataSuite1
95 |
96 | +---------------------------+--------------------------------------------------------------------------------------------------------------------------------+
97 | | Function | Purpose |
98 | +===========================+================================================================================================================================+
99 | | `PF_GetConstSequenceData` | Retrieves the read-only const sequence_data object for a rendering thread when Multi-Frame Rendering is enabled for an effect. |
100 | | | |
101 | | | PF_Err(*PF_GetConstSequenceData)(
PF_ProgPtr effect_ref,
PF_ConstHandle \*sequence_data);
|
102 | +---------------------------+--------------------------------------------------------------------------------------------------------------------------------+
103 |
104 | ```cpp
105 | static PF_Err Render(
106 | PF_InData *in_dataP,
107 | PF_OutData *out_dataP,
108 | PF_ParamDef *params[],
109 | PF_LayerDef *output )
110 | {
111 | PF_ConstHandle seq_handle;
112 |
113 | AEFX_SuiteScoperPF_Err PF_NewWorld(
PF_ProgPtr effect_ref,
A_long widthL,
A_long heightL,
PF_Boolean clear_pixB,
PF_PixelFormat pixel_format,
PF_EffectWorld \*worldP);
|
15 | +---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
16 | | `PF_DisposeWorld` | Disposes of a `PF_EffectWorld`. |
17 | | | |
18 | | | PF_Err PF_DisposeWorld(
PF_ProgPtr effect_ref,
PF_EffectWorld \*worldP);
|
19 | +---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
20 | | `PF_GetPixelFormat` | Get the pixel format for a given `PF_EffectWorld`. |
21 | | | |
22 | | | PF_Err PF_GetPixelFormat(
const PF_EffectWorld \*worldP,
PF_PixelFormat \*pixel_formatP);
|
23 | | | |
24 | | | `pixel_formatP` can be: |
25 | | | |
26 | | | - `PF_PixelFormat_ARGB32` - standard 8-bit RGB |
27 | | | - `PF_PixelFormat_ARGB64` - 16-bit RGB |
28 | | | - `PF_PixelFormat_ARGB128` - 32-bit floating point RGB |
29 | +---------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
30 |
--------------------------------------------------------------------------------
/docs/effect-details/memory-allocation.md:
--------------------------------------------------------------------------------
1 | # Memory Allocation
2 |
3 | Use After Effects for any memory allocations of significant size. For small allocations, you can use new and delete, but this is the exception, not the rule. In low-memory conditions (such as during RAM preview), it's very important that plug-ins deal gracefully with out-of-memory conditions, and not compete with After Effects for OS memory. By using our memory allocation functions, After Effects can know when to free cached images, to avoid memory swapping. Failing to use our functions for sizable allocations can cause lock-ups, crashes, and tech support calls. Don't do that.
4 |
5 | If you're wrapping existing C++ classes, create a base class that implements new and delete for that class and derive from it. To overload the STL, we don't recommend you overload global new and delete. Instead provide an allocator as part of the template definition.
6 |
7 | Handles passed to you by After Effects are locked for you before you're called, and unlocked once you return.
8 |
9 | ---
10 |
11 | ## PF_HandleSuite1
12 |
13 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
14 | | Function | Purpose | Replaces |
15 | +========================+==========================================================================================================+======================+
16 | | `host_new_handle` | Allocates a new handle. | `PF_NEW_HANDLE` |
17 | | | | |
18 | | | PF_Handle (*host_new_handle)(
A_HandleSize size);
| |
19 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
20 | | `host_lock_handle` | Locks a handle. | `PF_LOCK_HANDLE` |
21 | | | | |
22 | | | void (*host_lock_handle)(
PF_Handle pf_handle);
| |
23 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
24 | | `host_unlock_handle` | Unlocks a handle. | `PF_UNLOCK_HANDLE` |
25 | | | | |
26 | | | void (*host_unlock_handle)(
PF_Handle pf_handle);
| |
27 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
28 | | `host_dispose_handle` | Frees a handle. | `PF_DISPOSE_HANDLE` |
29 | | | | |
30 | | | void (*host_dispose_handle)(
PF_Handle pf_handle);
| |
31 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
32 | | `host_get_handle_size` | Returns the size, in bytes, of the reallocatable block whose handle is passed in. | `PF_GET_HANDLE_SIZE` |
33 | | | | |
34 | | | A_HandleSize (*host_get_handle_size)(
PF_Handle pf_handle);
| |
35 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
36 | | `host_resize_handle` | Resizes a handle. | `PF_RESIZE_HANDLE` |
37 | | | | |
38 | | | PF_Err (*host_resize_handle)(
A_HandleSize new_sizeL, PF_Handle \*handlePH);
| |
39 | +------------------------+----------------------------------------------------------------------------------------------------------+----------------------+
40 |
--------------------------------------------------------------------------------
/docs/effect-details/motion-blur.md:
--------------------------------------------------------------------------------
1 | # Motion Blur
2 |
3 | Effects handle their own motion blur, using [PF_InData>shutter_angle](../effect-basics/PF_InData.md#pf_indata-members) along with [PF_InData>shutter_phase](../effect-basics/PF_InData.md#pf_indata-members).
4 |
5 | The plug-in must set [PF_OutFlag_I_USE_SHUTTER_ANGLE](../effect-basics/PF_OutData.md#pf_outflags) so After Effects knows it needs this information.
6 |
7 | They must [check out](interaction-callback-functions.md#interaction-callback-functions) their own parameters at other times to examine their change over the shutter interval.
8 |
9 | If the plug-in checks out parameters outside this interval, set [PF_OutFlag_WIDE_TIME_INPUT](../effect-basics/PF_OutData.md#pf_outflags).
10 |
11 | Doing so allows After Effects to compare the parameters within the sampling interval, and determine if they've changed.
12 |
--------------------------------------------------------------------------------
/docs/effect-details/parameters-floating-point-values.md:
--------------------------------------------------------------------------------
1 | # Parameters & Floating Point Values
2 |
3 | We have something to admit to you; for years, even though we've given you 8 bit color values, we've internally used floating point representations behind your back.
4 |
5 | That's right, even with over-bright colors, we'd only ever tell you '255, 255, 255'. Yeah, right.
6 |
7 | Well, we can't live the lie any longer! Given a color parameter (passed to you by After Effects in your effect's parameter array), this function returns a floating point representation, including any high dynamic range component.
8 |
9 | ---
10 |
11 | ## PF_ColorParamSuite1
12 |
13 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
14 | | Function | Purpose |
15 | +=======================+=======================================================================================================================================================================================+
16 | | `PF_GetFloatingPoint` | PF_Err PF_GetFloatingPointColorFromColorDef(
PF_ProgPtr effect_ref,
const PF_ParamDef \*color_defP,
PF_PixelFloat \*fp_colorP);
|
17 | | | |
18 | | `ColorFromColorDef` | |
19 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
20 |
21 | ---
22 |
23 | ## PF_PointParamSuite1
24 |
25 | We also provide a way to get floating point values for point parameters.
26 |
27 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
28 | | Function | Purpose |
29 | +=======================+=======================================================================================================================================================================================+
30 | | `PF_GetFloatingPoint` | PF_Err PF_GetFloatingPointValueFromPointDef(
PF_ProgPtr effect_ref,
const PF_ParamDef \*point_defP,
A_FloatPoint \*fp_pointP);
|
31 | | | |
32 | | `ValueFromPointDef` | |
33 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
34 |
35 | ---
36 |
37 | ## PF_AngleParamSuite1
38 |
39 | New in CS6.0.2, we now provide a way to get floating point values for angle parameters.
40 |
41 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
42 | | Function | Purpose |
43 | +=======================+=======================================================================================================================================================================================+
44 | | `PF_GetFloatingPoint` | PF_Err PF_GetFloatingPointValueFromAngleDef(
PF_ProgPtr effect_ref,
const PF_ParamDef \*angle_defP,
A_FloatLong \*fp_valueP);
|
45 | | | |
46 | | `ValueFromAngleDef` | |
47 | +-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
48 |
--------------------------------------------------------------------------------
/docs/effect-details/pixel-aspect-ratio.md:
--------------------------------------------------------------------------------
1 | # Pixel Aspect Ratio
2 |
3 | Effects must respond correctly to footage with non-square pixels, and non-uniform downsampling factors. Even different layer parameters can have different pixel aspect ratios! Doing so isn't difficult once you understand the concepts involved.
4 |
5 | Simple effects needn't do any work to match up [point parameters](../effect-basics/parameters.md) to the actual pixels in the output. Point parameters are given to the effect scaled for downsample factor and pixel aspect ratio; they are in the coordinate system of the input buffer. This provides an implicit "pixel coordinate system." This coordinate system is handy and easy to understand. But effects that use absolute pixel measurements or geometry must take a deeper look at the relationship between the input buffer and the final rendered image.
6 |
7 | ---
8 |
9 | ## Don't Assume Pixels Are Square, Or 1-To-1
10 |
11 | First, it is not necessarily a square coordinate system, due to both pixel aspect ratio and non-uniform downsample factor. The final rendered image can be stretched or squashed horizontally, relative to the pixels your effect processes. Circles will appear as ellipses, squares as rectangles. The distance between two points varies based on their angle in this coordinate system; anything rotated in this system is skewed, in the final output.
12 |
13 | Second, even if it *is* a square coordinate system, it's not necessarily the same size as the final output. This means that any slider which defines a size in pixels will be a problem when the image is rendered downsampled; the width of anti-aliasing filters changes based on downsample factor.
14 |
15 | Sometimes these issues aren't a problem. Any effect that colors pixels based solely on a linear function of the x and y coordinates need not bother with pixel aspect ratio and downsample factor at all. Staying in the input coordinate space is an option, though you must account for pixel aspect ratio and downsample factor elsewhere.
16 |
17 | Suppose you're writing a particle system effect that sprays textured sprites from a source position defined by an effect control point. Using pixel coordinates to represent the particle positions seems fine (as long as the particles don't have to rotate around a point), but when you go to actually *render* the particle textures, you'll have to scale them by pixel aspect ratio and downsample factor.
18 |
19 | If an effect already has coordinate transformation machinery in its pipeline, there's an alternative that's often simpler. Many algorithms require some sort of coordinate transformation; using matrices to set up a transformation, for example. But there are other easily adaptable algorithms, for example a texture generation effect that computes the value of each pixel based solely on its position. In this case, the code must take the raw pixel position and account for pixel aspect ratio and downsample factor.
20 |
21 | ---
22 |
23 | ## Suggested Approach
24 |
25 | The simplest way to get all of this right is to work entirely in full resolution square coordinates, then scale by downsample factor and pixel aspect ratio as a final output transformation. Since point parameters are always reported in input buffer coordinates, convert them to full-resolution square coordinates before use. With this approach you don't need to worry about sliders which define a size in pixels; just interpret them as defining size in full-resolution vertical pixels.
26 |
27 | 1. When getting your point parameters, go immediately to floating point and a full resolution square pixel system, like this.
28 |
29 | ```cpp
30 | x *= in_data>pixel_aspect_ratio.num / (float)in_data>pixel_aspect_ratio.den;
31 | x *= in_data>downsample_x.den / (float)in_data>downsample_x.num;
32 | y *= in_data>downsample_y.den / (float)in_data>downsample_y.num;
33 | ```
34 |
35 | 1. Perform all setup (define transformation matrices, generate coordinates for later scan conversion, compute values based on the distance between points, rotating things, et cetera) in this coordinate space. Note that you're not actually dealing with pixels in this stage; you're just manipulating coordinates or coordinate transformations.
36 | 2. To go back to a coordinate system that corresponds directly to the pixels of the output buffer, undo the transformations from step one. Do this as late as possible, so as little code as possible needs to deal with this non-square space. If you're using matrices, this would be a final output transformation. For an effect which renders something based on the coordinate of each pixel, iterate over the output pixels and convert pixel coordinates to square coordinates before doing any processing for that pixel.
37 |
38 | This may seem like extra work, but most reasonably complex effects like this have a coordinate transformation step anyway; and if they don't, they still need one to handle pixel aspect ratio and downsample factor correctly.
39 |
40 | ---
41 |
42 | ## Applying User Input In Pixels
43 |
44 | After Effects does all of its stretching horizontally so as to not to introduce unnecessary field interpolations; when pixels are used as a unit, we think of them as vertical pixels.
45 |
46 | ---
47 |
48 | ## Test Test Test!
49 |
50 | Test at 1/2, 1/4, and custom resolutions and compare the output. Use an anamorphic (2:1) pixel aspect ratio composition to track down bugs in pixel aspect ratio handling (it really makes them obvious), and be sure to test with different horizontal and vertical downsample factors.
51 |
52 | Some developers have reported problems with the downsample factors provided by some "After Effects compatible" plug-in hosts being zero. Check for zero before dividing.
53 |
--------------------------------------------------------------------------------
/docs/effect-details/tips-tricks.md:
--------------------------------------------------------------------------------
1 | # Tips & Tricks
2 |
3 | ## Best Practices
4 |
5 | If your prototypes are anything like ours, the first version of your plug-in that runs without crashing differs radically from the version that actually ships.
6 |
7 | How your plug-in responds to things like downsampling, errors and exceptions, pixel aspect ratio, out-of-memory situations, and being interrupted while processing determines how usable it is (and how many support requests you'll have to handle).
8 |
9 | ---
10 |
11 | ## Responsiveness
12 |
13 | Make your plug-ins as responsive as possible using `PF_ABORT()` and `PF_PROGRESS()` from [Interaction Callbacks](interaction-callback-functions.md#interaction-callbacks).
14 |
15 | We actually test all our effects for interrupt-ability; you'd be surprised how cranky users can get waiting for your pokey effect to finish processing a film resolution sequence!
16 |
17 | After Effects' iteration functions inherently provide this functionality; you don't need to worry about calling the above functions from within your pixel processing functions.
18 |
19 | ---
20 |
21 | ## Make Your Effect Easy To Find
22 |
23 | It's possible to have your effect show up in the "Effects & Presets" palette when users search for something other than the plug-in's name.
24 |
25 | Apply your effect (leaving the settings at default, unless you're very certain the user will want something different when they search for the given term), and select "Save selection as animation preset" from the effect controls palette.
26 |
27 | Save it to the name by which you want users to find the plug-in.
28 |
29 | Have your plug-in's installer put the resultant .ffx file into the \\Presets directory, next to the After Effects executable.
30 |
31 | Your preset will show up when users search for the name to which it was saved.
32 |
33 | ---
34 |
35 | ## Sampling Pixels At (x,y)
36 |
37 | Sometimes, instead of just processing every pixel, you'll want to get to a specific offset within the input frame. Below is one way to sample the pixel at a given (x,y) location; similar code could be used to write to the given location.
38 |
39 | ```cpp
40 | PF_Pixel *sampleIntegral32(PF_EffectWorld &def, int x, int y){
41 | return (PF_Pixel*)((char*)def.data +
42 | (y * def.rowbytes) +
43 | (x * sizeof(PF_Pixel)));
44 | }
45 |
46 | PF_Pixel16 *sampleIntegral64(PF_EffectWorld &def, int x, int y){
47 | assert(PF_WORLD_IS_DEEP(&def));
48 | return (PF_Pixel16*)((char*)def.data +
49 | (y * def.rowbytes) +
50 | (x * sizeof(PF_Pixel16)));
51 | }
52 | ```
53 |
54 | Special thanks to Paul Miller for answering this question.
55 |
56 | ---
57 |
58 | ## Where's The Center Of A Pixel?
59 |
60 | Deeeeeep, man. After Effects rotates around the upper left corner of the upper left pixel when the anchor point (see User Documentation) is (0,0).
61 |
62 | However, the subpixel sample and area sample callbacks actually treat (.0, .0) as a direct hit. To compensate for this, subtract 0.5 from x and y values before calling those functions.
63 |
64 | The matrix functions (`transform_world` from [PF_WorldTransformSuite1](graphics-utility-suites.md#pf_worldtransformsuite1)) don't have this problem.
65 |
66 | When translating an image by a subpixel amount, make the output layer one pixel wider than its input, and leave the origin at (0,0).
67 |
68 | ---
69 |
70 | ## Text Layer Origin
71 |
72 | Almost all layer types have their origin in the upper-left corner. Not so with text layers!
73 |
74 | A text layer origin by default is at the bottom-left baseline position of the first character. You can see this if you create a text item and then pick the layer so the anchor point shows up.
75 |
76 | Look at where the default anchor point location is. The transform is not at the corner of the layer rectangle.
77 |
78 | ---
79 |
80 | ## Clean Slate
81 |
82 | You don't necessarily begin effect processing with a clean output slate. Our Gaussian blur filter, in an effort to do so, performs the following before rendering:
83 |
84 | ```cpp
85 | src_rect.left = in_data>output_origin_x;
86 | src_rect.right = src_rect.left + input>width;
87 | src_rect.top = in_data>output_origin_y;
88 | src_rect.bottom = src_rect.top + input>height;
89 |
90 | err = PF_FILL(NULL, NULL, output);
91 |
92 | if (!err) {
93 | err = PF_COPY(¶ms[0]>u.ld, output, NULL, &src_rect);
94 | }
95 | ```
96 |
97 | ---
98 |
99 | ## Caching Behavior
100 |
101 | After Effects provides numerous ways to specify caching behavior. `PF_OutFlag_NON_PARAM_VARY`, `PF_OutFlag_WIDE_TIME_INPUT`, `PF_OutFlag_I_USE_SHUTTER_ANGLE`, `PF_OutFlag_I_SYNTHESIZE_AUDIO`, `PF_OutFlag2_I_USE_3D_CAMERA`, and `PF_OutFlag2_I_USE_3D_LIGHTS` (all from [PF_OutFlags](../effect-basics/PF_OutData.md#pf_outflags)) all influence caching decisions.
102 |
103 | Supporting [dynamic outflags](../effect-basics/PF_OutData.md#pf_outflags) can greatly improve performance, preventing After Effects from invalidating your effect's cache as aggressively as it otherwise would.
104 |
105 | Confirm that your plug-in performs well with different After Effects cache settings. Does your plug-in get called to update as often as expected, or does After Effects think it has valid pixels when you think it doesn't?
106 |
107 | ---
108 |
109 | ## Global Performance Cache Consideratons
110 |
111 | With the new caching in CS6, you may need to clear cached frames after changing your effect's rendering, so that frames rendered and stored in the cache prior to the change will not be reused. To do so manually during development:
112 |
113 | 1. In Preferences > Media & Disk Cache, disable the Disk Cache
114 | 2. Click "Empty Disk Cache" just to be sure (disabling the Disk Cache in step 1 only disables the *writing* of disk cache, not necessarily the usage)
115 | 3. Relaunch
116 |
117 | If you ever encounter a glitch, it likely a legitimate bug in your effect, such as improper rectangle handling in SmartFX.
118 |
119 | On the other hand, if you fix a rendering bug in your plug-in and ship an update, you can't expect all users will empty their disk caches. A user may have a disk cache of the buggy frame and it needs to be invalidated. What to do? Update your plug-in's effect version. This value (and the AE build number) is part of the cache key, so if you update it any frames cached containing content from your plug-in will no longer match.
120 |
121 | ---
122 |
123 | ## Some Thoughts On Time From A Long-Time Developer
124 |
125 | Stoney Ballard put together the following summary of how time works with effects; you may find it helpful.
126 |
127 | There are five `in_data` parameters that describe time to a filter:
128 |
129 | - `current_time`
130 | - `time_step`
131 | - `local_time_step`
132 | - `total_time`
133 | - `time_scale`
134 |
135 | Their values are dependent on:
136 |
137 | - The frame being rendered
138 | - The duration of the layer and composition The frame rate of the comp
139 | - Any Time Stretch Any Time Remapping
140 | - The time behavior of an outer composition (one enclosing the composition with the layer being filtered)
141 | - The setting of the "Preserve frame rate when nested or in render queue" (PFR) switch
142 |
143 | The frame being rendered affects current_time. It is expressed in the local (layer) time system. If the PFR switch is off, current_time may be any non-negative value. If on, it will be restricted to a multiple of time_step and local_time_step. Layer duration affects only total_time. Comp duration is a factor only when Time Remapping (TR) is on. In that case, total_time is the larger of layer duration and composition duration. Composition frame rate affects only the time_scale. Time Stretch affects only time_step and local_time_step. If the time stretch is negative, these values are negative. Even if the layer's duration (as seen in
144 |
145 | the comp) changes, total_time remains unaffected. This works as if Time Stretch was *above* a filter, but *below* an outer comp. PFR does not alter the effect of Time Stretch. Time Stretch is different than an outer comp, since it affects both step params equally, while an outer comp affects only time_step.
146 |
147 | Time Remapping happens *below* the filter, so that it does not affect the time params other than the total_time. When TR is on, the layer is lengthened to the same as the comp (but never shortened), regardless of how much time it actually takes, or where in the comp the layer is. This may cause total_time to be larger. It has nothing to do with the actual time map, just whether or not it's enabled.
148 |
149 | The biggest variation comes from being nested in an outer comp, unless PFR is on. When PFR is on, a filter is completely isolated from time variations in an outer comp. Of course, current_time will not necessarily move in increments of time_step in that case. It may skip frames or go backwards.
150 |
151 | When PFR is off, local_time_step, total_time, and time_scale remain set to what they were for the inner comp, but time_step contains the time to the next frame in the outer comp, expressed in the local time system. This may be any value, including 0. This can be interpreted as an instantaneous time rate, rather than a duration. A 0 value can last for an arbitrary number of rendered frames, but the current_time won't change on the local layer.
152 |
153 | Looked at from the other direction:
154 |
155 | current_time is quantized to time_step intervals unless rendering an outer comp with PFR off for the inner comp. This is the current time in the layer, not in any comp.
156 |
157 | The value of local_time_step is affected only by Time Stretch. It can never be zero, but it can be negative.
158 |
159 | time_step and local_time_step are always the same value unless rendering an outer comp with PFR off. time_step is also affected by the time behavior of an outer comp (with PFR off). It can have any value, positive, negative, or zero, and can be different for every frame (of the outer comp). time_step can be used to determine the duration of the current frame (with PFR off).
160 |
161 | total_time is the duration of the layer, unless Time Remapping is on, which makes it the larger of the layer duration and the duration of the comp.
162 |
163 | time_scale is the scale such that total_time / time_scale is the layer duration in seconds in its comp. It is affected only by the comp frame rate, although presumably all the time values could be scaled proportionately for any reason.
164 |
165 | A layer's intrinsic frame rate (if it has one) is not visible anywhere, although it's usually the same as the comp frame rate. If a filter needs to access the actual frames of a clip, it can do so
166 |
167 | only by being in a comp of the same frame rate, and with no Time Stretch or Time Remapping applied to its layer. It should use local_time_step to determine where the frames are.
168 |
169 | ---
170 |
171 | ## Rate x Time == Pain!
172 |
173 | Be careful if one of your parameters is a speed or velocity parameter. Consider the ripple effect. It assumes a constant and uses the current time to determine how far along the ripple has gone (d = v \* t). If the user interpolates the speed over time, you should integrate the velocity function from time zero to the current time. Ripple does *not* do this, but provides a "phase" parameter that the user can interpolate as they wish, providing correct results as long as the speed is set to zero. If you want to provide the correct behavior, you can sample (and integrate) the speed parameter from the beginning of time until the current time using PF_CHECKOUT_PARAM(), or you can provide a "phase" or "distance" parameter and warn the user about interpolating the speed. The cost of checking out many parameter values is negligible compared to rendering, and is the recommended approach.
174 |
175 | If you check out parameter values at other times, or use layer parameters at all, you *must* check in those parameters when finished, even if an error has occurred. Remember, checked-out parameters are read-only.
176 |
177 | ---
178 |
179 | ## Testing
180 |
181 | Try using your plug-in in RAM previews to ensure you handle out-of-memory conditions gracefully. Does your plug-in handle running out of memory gracefully?
182 |
183 | If you receive `PF_Err_OUT_OF_MEMORY` (from [Error Codes](../effect-basics/errors.md#error-codes)) when requesting memory, do you pass it back to After Effects?
184 |
185 | What happens when your video effect is applied to an audio-only layer? Test with projects created using older versions of your plug-in.
186 |
--------------------------------------------------------------------------------
/docs/effect-ui-events/PF_EventExtra.md:
--------------------------------------------------------------------------------
1 | # PF_EventExtra
2 |
3 | This structure provide context information for the current event. After Effects passes a pointer to this structure in the extra parameter of the [Entry Point](../effect-basics/entry-point.md) function.
4 |
5 | The `PF_EventUnion` (sent in the `PF_EventExtra`) varies with the event type, and contains information specific to that event.
6 |
7 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
8 | | Member | Purpose |
9 | +=================+========================================================================================================================================================================================+
10 | | `contextH` | Handle to the `PF_Context`. |
11 | | | |
12 | | | This drawing context is used with the [Drawbot suites](custom-ui-and-drawbot.md) for drawing, and also for the [UI Callbacks](ui-callbacks.md). |
13 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
14 | | `e_type` | Which [event](effect-ui-events.md) is occurring. |
15 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
16 | | `u` | A [PF_EventUnion](PF_EventUnion.md) containing information specific to the event. |
17 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
18 | | `effect_win` | A `PF_EffectWindowInfo` about the event if it occurs within the effects window. |
19 | | | |
20 | | | Otherwise, as of After Effects 5.0, effect_win can be replaced by a `PF_WindowUnion`. |
21 | | | |
22 | | | This struct contains both a `PF_EffectWindowInfo` and an `PF_ItemWindowInfo`, which (for now) is simply the port rectangle for the item window. |
23 | | | |
24 | | | Replacement only occurs if `PF_USE_NEW_WINDOW_UNION` was defined during compilation; otherwise, it will continue to be just a `PF_EffectWindowInfo`. |
25 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
26 | | `cbs` | Pointer to [UI Callbacks](ui-callbacks.md), which are needed to translate points between layer, composition, and screen coordinate systems. |
27 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
28 | | `evt_in_flags` | Event Input Flags. This currently contains only one value, `PF_EI_DONT_DRAW`, which you should check before drawing! |
29 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
30 | | `evt_out_flags` | One or more of the following, combined with a bitwise OR operation: |
31 | | | |
32 | | | - `PF_EO_NONE` |
33 | | | - `PF_EO_HANDLED_EVENT` tells After Effects you've handled the event. |
34 | | | - `PF_EO_ALWAYS_UPDATE` forces After Effects to rerender the composite in response to every click or drag; this is the same behavior generated by 'alt-scrubbing' the parameter value. |
35 | | | - `PF_EO_NEVER_UPDATE` prevents After Effects from rerendering the composite until the user stops clicking and dragging. |
36 | | | - `PF_EO_UPDATE_NOW` tells After Effects to update the view immediately after the event returns after calling `PF_InvalidateRect` |
37 | +-----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
38 |
39 |
40 | ---
41 |
42 | ## PF_Context
43 |
44 | PF_Context details the event's UI context.
45 |
46 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
47 | | Member | Purpose |
48 | +====================+====================================================================================================================================================================+
49 | | `magic` | Do not change. |
50 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
51 | | `w_type` | The window type. If you have Custom Comp and ECW UIs in the same plug-in, this is the way to differentiate between them (what kind of masochist are you, anyway?). |
52 | | | |
53 | | | - `PF_Window_COMP`, |
54 | | | - `PF_Window_LAYER`, |
55 | | | - `PF_Window_EFFECT` |
56 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
57 | | `reserved_flt` | Do not change. |
58 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
59 | | `plugin_state[4]` | An array of 4 `A_longs` which the plug-in can use to store state information for a given context. |
60 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
61 | | `reserved_drawref` | A `DRAWBOT_DrawRef` for use with the [Drawbot suites](custom-ui-and-drawbot.md). |
62 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
63 | | `*reserved_paneP` | Do not change. |
64 | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
65 |
66 | ---
67 |
68 | ## PF_EffectWindowInfo
69 |
70 | If an event occurs in the ECP, an PF_EffectWindowInfo is sent in PF_EventExtra.
71 |
72 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
73 | | Member | Purpose |
74 | +=====================+============================================================================================================================================+
75 | | `index` | This indicates which parameter in the effect window is being affected. The controls are numbered from 0 to the number of controls minus 1. |
76 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
77 | | `area` | This indicates if the control title (`PF_EA_PARAM_TITLE`) or the control itself (`PF_EA_CONTROL`) are being affected. |
78 | | | |
79 | | | The title is the area still visible when the parameter's topic ("twirly") is spun up. |
80 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
81 | | `current_frame` | A PF_Rect indicating the full frame of the area occupied by the control. |
82 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
83 | | `param_title_frame` | A PF_Rect indicating the title area of the control. |
84 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
85 | | `horiz_offset` | A horizontal offset from the left side of the title area in which to draw into the title. |
86 | +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
87 |
--------------------------------------------------------------------------------
/docs/effect-ui-events/effect-ui-events.md:
--------------------------------------------------------------------------------
1 | # Effect UI & Events
2 |
3 | Effects can provide custom UI in two areas: (1) the Effect Controls Window (custom ECW UI), and (2) the Composition or Layer Windows (Custom Comp UI).
4 |
5 | Effects that use custom UI should set `PF_OutFlag_CUSTOM_UI` (from [PF_OutFlags](../effect-basics/PF_OutData.md#pf_outflags) during `PF_Cmd_GLOBAL_SETUP` (from [Global Selectors](../effect-basics/command-selectors.md#global-selectors)), and handle the PF_Cmd_EVENT selector.
6 |
7 | Custom ECW UI allows an effect to provide a parameter with a customized control, which can be used either with standard parameter types or [Arbitrary Data Parameters](../effect-details/arbitrary-data-parameters.md#arbitrary-data-parameters).
8 |
9 | Parameters that have a custom UI should set `PF_PUI_CONTROL` (from [Parameter UI Flags](../effect-basics/PF_ParamDef.md#parameter-ui-flags)) when [adding the parameter](../effect-details/interaction-callback-functions.md#interaction-callbacks).
10 |
11 | Custom Comp UI allows an effect to provide direct manipulation of the video in the Composition or Layer Windows.
12 |
13 | When the effect is selected, the Window can overlay custom controls directly on the video, and can handle user interaction with those controls, to adjust parameters more quickly and naturally.
14 |
15 | Effects should register themselves to receive events by calling PF_REGISTER_UI.
16 |
17 | After Effects can send events to effects for user interface handling and parameter management, integrating effects into its central message queue.
18 |
19 | While many events are sent in response to user input, After Effects also sends events to effects which manage arbitrary data parameters.
20 |
21 | The type of event is specified in [PF_EventExtra->e_type](PF_EventExtra.md#pf_eventextra) and the various events are described below.
22 |
23 | ---
24 |
25 | ## Events
26 |
27 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
28 | | Event | Indicates |
29 | +==========================+=================================================================================================================================================+
30 | | `PF_Event_NEW_CONTEXT` | The user created a new context (probably by opening a window) for events. |
31 | | | |
32 | | | The plug-in is allowed to store state information inside the context using the context handle. |
33 | | | |
34 | | | [PF_EventUnion](PF_EventUnion.md#pf_eventunion) contains valid context and type, but everything else should be ignored. |
35 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
36 | | `PF_Event_ACTIVATE` | The user activated a new context (probably by bringing a window into the foreground). [PF_EventUnion](PF_EventUnion.md#pf_eventunion) is empty. |
37 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
38 | | `PF_Event_DO_CLICK` | The user clicked within the effect's UI. [PF_EventUnion](PF_EventUnion.md#pf_eventunion) contains a `PF_DoClickEventInfo`. |
39 | | | |
40 | | | Handle the mouse click and respond, passing along drag info; see sample code), within a context. |
41 | | | |
42 | | | !!! note |
43 | | | As of 7.0, do *not* block until mouse-up; instead, rely on `PF_Event_DRAG`. |
44 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
45 | | `PF_Event_DRAG` | Also a Click Event, [PF_EventUnion](PF_EventUnion.md#pf_eventunion) contains a `PF_DoClickEventInfo`. |
46 | | | |
47 | | | Request this by returning `send_drag == TRUE` from `PF_Event_DO_CLICK`. |
48 | | | |
49 | | | Do this so After Effects can see new data from the user's changes. |
50 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
51 | | `PF_Event_DRAW` | Draw! [PF_EventUnion](PF_EventUnion.md#pf_eventunion) contains a `PF_DrawEventInfo`. |
52 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
53 | | `PF_Event_DEACTIVATE` | The user has deactivated a context (probably by bringing another window into the foreground). `PF_EventUnion` is empty. |
54 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
55 | | `PF_Event_CLOSE_CONTEXT` | A context has been closed by the user. `PF_EventUnion` will be empty. |
56 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
57 | | `PF_Event_IDLE` | A context is open but nothing is happening. `PF_EventUnion` is empty. |
58 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
59 | | `PF_Event_ADJUST_CURSOR` | The mouse is over the plug-in's UI. Set the cursor by changing the `PF_CursorType` in the `PF_AdjustCursorEventInfo`. |
60 | | | |
61 | | | Use OS-specific calls to implement a custom cursor; tell After Effects you've done so by setting `PF_CursorType` to `PF_Cursor_CUSTOM`. |
62 | | | |
63 | | | Use an After Effects cursor whenever possible to preserve interface continuity. |
64 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
65 | | `PF_Event_KEYDOWN` | Keystroke. [PF_EventUnion](PF_EventUnion.md#pf_eventunion) contains a `PF_KeyDownEvent`. |
66 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
67 | | `PF_Event_MOUSE_EXITED` | New in CS6. Notification that the mouse is no longer over a specific view (layer or comp only). |
68 | +--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
69 |
--------------------------------------------------------------------------------
/docs/effect-ui-events/tips-and-tricks.md:
--------------------------------------------------------------------------------
1 | # Tips & Tricks
2 |
3 | ## UI Performance
4 |
5 | Experiment with `PF_EO_ALWAYS_UPDATE` and `PF_EO_NEVER_UPDATE` from [PF_EventExtra](PF_EventExtra.md), to find a happy medium between responsiveness and accuracy.
6 |
7 | On macOS, the foreground and background colors are not set to white and black when custom UI draw events are sent.
8 |
9 | This is by design; you don't have to change the background color when you're drawing directly into our context.
10 |
11 | ---
12 |
13 | ## How Deep Are My Pixels?
14 |
15 | There is no way to determine the bit depth of the layer(s) being processed during events.
16 |
17 | However, you can cache the last-known pixel depth in your sequence data.
18 |
19 | Better still, you can have your fixed and float slider parameters rely on the `PF_ValueDisplayFlags` in their parameter definitions; if you use this, it will have your parameters' UI respond to the user's preferences for pixel display values.
20 |
21 | You can also check the depth of your input world during `PF_Cmd_RENDER`.
22 |
23 | ---
24 |
25 | ## Arbitrary Data
26 |
27 | An arbitrary data parameter is an excellent way to manage your custom UI.
28 |
29 | Store state, preference, and last-item-used information in an arb, and you'll always be able to recover it.
30 |
31 | After Effects manages parameters with a much richer message stream than custom UIs.
32 |
33 | ---
34 |
35 | ## Custom UI Implementation for Color Sampling, Using Keyframes
36 |
37 | A plug-in may want to get a color from a layer within a composition. The user would use the eyedropper associated with a color parameter, or the plug-in's custom composition panel UI, to select the point.
38 |
39 | During the click event, the plug-in converts the coordinates of the click into layer space, and stores that information in sequence data. It then forces a re-render, during which it has access to the color of the layer point corresponding to the stored coordinates.
40 |
41 | The plug-in stores the color value in sequence data, and cancels the render, requesting a redraw of the affected parameter(s).
42 |
43 | Finally, during the draw, the plug-in adds appropriate keyframes to its color parameter stream using the [AEGP_KeyframeSuite](../aegps/aegp-suites.md#aegp_keyframesuite3).
44 |
45 | Yes, this means the effect needs to [Cheating Effect Usage of AEGP Suites](../aegps/cheating-effect-usage-of-aegp-suites.md) and use the AEGP API.
46 |
--------------------------------------------------------------------------------
/docs/history.md:
--------------------------------------------------------------------------------
1 | # Version History
2 |
3 | | Revision Date | Documentor | Notes |
4 | | ---------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
5 | | 24 Feb 2025 | Sean Jenkin | 25.2 SDK Release - AEGP_GetLayerObjectType can now return AEGP_ObjectType_3D_MODEL if the object type is a 3D model |
6 | | 5 May 2023 | Jason Bartell | Update Color Settings suite to AEGP_ColorSettingsSuite5 with new OCIO calls, and added URL property to the PiPL. See [AEGP_ColorSettingsSuite5](aegps/aegp-suites.md#aegp_colorsettingssuite5) and [PiPL Resources](intro/pipl-resources.md) respectively for more details. |
7 | | 18 October 2022 | Field Kuang | Update layer suite to AEGP_LayerSuite9 with 3 new Track Matte methods. See [AEGP_LayerSuite9](aegps/aegp-suites.md#aegp_layersuite9) for more details |
8 | | 26 October 2021 | Sean Jenkin | After Effects 2022 (22.0) release. Updates the maxiumum threads for PF_Iterate. |
9 | | 31 March 2021 | Sean Jenkin | Updated Multi-Frame Rendering documentation for sequence_data changes and Compute Cache system. Added information for supporting Universal Mac binaries for Apple Silicon effect plugins. |
10 | | 1 June 2020 | Field Kuang | Multi-Frame Rendering is now supported in AE Beta builds. See [Multi-Frame Rendering in AE](effect-details/multi-frame-rendering-in-ae.md) for more details. |
11 | | 1 November 2018 | Bruce Bullis | 16.0 release |
12 | | 10 November 2017 | Zac Lam | 15.0 release |
13 | | 12 May 2017 | Zac Lam | CC 2017.1 (14.2) release |
14 | | 2 November 2016 | Zac Lam | CC 2017 (14.0) release. |
15 | | 21 July 2015 | Zac Lam | CC 2015 (13.5) release. |
16 | | 12 June 2014 | Zac Lam | CC 2014 (13.0) release. Corrections for accuracy. Removed old version references. |
17 | | 15 July 2013 | Zac Lam | CC (12.0) release. API version changes, misc small clarifications, more details in [AEIOs](aeios/aeios.md). |
18 | | 26 April 2012 | Zac Lam | CS6 (11.0) release. Big reorganization of the [AEGPs](aegps/aegps.md) and [Artisans](artisans/artisans.md). Many additions throughout. |
19 | | 2 May 2011 | Zac Lam | CS5.5 (10.5) release. |
20 | | 28 April 2010 | Zac Lam | CS5 (10.0) release. 64-bit porting info. Drawbot. |
21 | | 4 May 2009 | Zac Lam | CS4 (9.0) release. Complete reorganization of first three chapters. Fleshed out documentation on Premiere Pro. |
22 | | 1 July 2007 | Bruce Bullis | CS3 (8.0) release. |
23 | | 4 April 2006 | Bruce Bullis | Updated to reference new development system requirements and Xcode-specific issues. Some editing. |
24 | | 1 December 2005 | Bruce Bullis | Updated for 7.0. Added SmartFX documentation. Noted current suite version numbers throughout. Numerous editorial changes. Documented many new AEGP suite functions. |
25 | | 4 April 2004 | Bruce Bullis | Updated for 6.5. Expanded and corrected all documentation. Added documentation of all new AEGP functions. |
26 | | 20 July 2003 | Bruce Bullis | Major overhauls for After Effects 6.0. Added documentation for all new (and some old) suites, and many supporting details for effects. |
27 | | 4 March 2002 | Bruce Bullis | Updated Mac OS X details, expanded AEIO and AEGP documentation. |
28 | | 1 December 2001 | Bruce Bullis | 5.5 release. Added information on new outflags, PiPL changes, and additions and changes to the AEGP API. Numerous clarifications and edits. |
29 | | 2 February 2001 | Bruce Bullis | 5.0 release. Entire document edited and reformatted. Sections on 16 bit-per-channel color and parameter supervision, as well as the entire AEGP chapter, have all substantially expanded. |
30 | | 9 September 1999 | Bruce Bullis | Revised for 4.1; added General plug-ins and AEGP information. Added information on new selectors, resize handle. |
31 | | 1 January 1999 | Bruce Bullis | Version 4.0 SDK Release 1 - Added information on new global flags, custom data types, utilization of PICA suites, CustomUI messaging and parameter supervision, new callbacks. many editorial changes. |
32 | | 1 May 1998 | Bruce Bullis | Version 3.1 SDK Release 6 - Editorial changes only |
33 | | 17 April 1997 | Brian Andrews | Version 3.1 SDK Release 3 - First public release (really a pre-release) of the SDK for Windows development. |
34 | | 13 Nov. 1996 | Brian Andrews | Version 3.1 SDK Release 2 - Minor updates. |
35 | | 21 June 1996 | Brian Andrews | Version 3.1 - Final 3.x release. |
36 | | 5 March 1996 | Brian Andrews | Version 3.0 - Preliminary release for the After Effects developer kitchen. |
37 | | August 1994 | Dave Herbstman Dan Wilk | Version 2.0.1 - Added support for PowerPC. |
38 | | January 1994 | Dan Wilk | Version 2.0 - Updates. |
39 | | January 1993 | Russell Belfer | Version 1.0 - Initial SDK release. |
40 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | Welcome to the Adobe® After Effects® Software Development Kit!
4 |
5 | This is a living document and is constantly being updated and edited. The latest public version of the SDK is available at: [https://www.adobe.io/after-effects/](https://www.adobe.io/after-effects/)
6 |
7 | If you need more information, your question may already be answered on the After Effects SDK forum: [After Effects SDK Forum](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-sdk)
8 |
9 | Use the search box there, and post a new question if your question hasn’t already been answered.
10 |
11 | ---
12 |
13 | ## About
14 |
15 | This document has changed much over the years. Part encyclopedia, part how-to guide, with multiple sedimentary layers of accreted information from more than two decades of API development and refinement.
16 |
17 | Yes, there does need to be one source of information about every last niggling detail of the After Effects APIs. However, since no human in their right mind would ever want to *read* such a document, we've tried to keep it involving and interesting.
18 |
19 | As opportunity allows, we'll try to include more diagrams, illustrations, and purdy pickshurs explaining API intricacies.
20 |
21 | As always, your input is valued and appreciated.
22 |
23 | ---
24 |
25 | ## Organization
26 |
27 | The [What Can I Do With This SDK?](intro/what-can-i-do.md) provides an overview of the integration possibilities with After Effects. It explains what plug-ins are, and how they work with After Effects. It describes the sample projects, and how to modify them. It explains where to install plug-ins, and what resources they use.
28 |
29 | The basics of effect plug-ins are discussed in [Effect Basics](effect-basics/effect-basics.md). This overview provides information on the function parameters passed to and from an effect plug-in's entry point. It describes capability flags, effect parameters, and image buffers.
30 |
31 | [Effect Details](effect-details/effect-details.md) dives into the details of developing a complete effect plug-in using the many provided callback functions. It also provides many testing ideas to ensure the plug-in is stabile.
32 |
33 | [SmartFX](smartfx/smartfx.md) is the extension to the effect plug-in API to support 32-bit floating point images.
34 |
35 | [Effect UI & Events](effect-ui-events/effect-ui-events.md) covers events sent to effect plug-ins, how to incorporate custom user interface elements, parameter supervision, and the reliance of custom data parameter types on Custom UI messaging.
36 |
37 | [Audio](audio/audio.md) effects are covered in... [Audio](audio/audio.md).
38 |
39 | [AEGPs](aegps/aegps.md) details the After Effects General Plug-in (AEGP) API. Provided callback functions, hooking into internal messaging, manipulating the current contents of open projects and handling menu commands are all covered at length.
40 |
41 | [Artisans](artisans/artisans.md) covers specialized plug-in 3D renderer AEGPs.
42 |
43 | [AEIOs](aeios/aeios.md), specialized AEGPs which handle file input and output.
44 |
45 | [Premiere Pro & Other Hosts](ppro/ppro.md) discusses issues related to compatibility with Premiere Pro and other applications that support a subset of After Effects plug-ins.
46 |
47 | ---
48 |
49 | ## Documentation Conventions
50 |
51 | Functions, structure names and general C/C++ code are in Courier; MyStruct and MyFunction();
52 |
53 | Text in blue is hyperlinked.
54 |
55 | Command selectors are italicized; *PF_Cmd_RENDER*.
56 |
57 | ---
58 |
59 | ## A Note About Coding Style
60 |
61 | Because we use the public APIs for our own plug-ins, our coding guidelines are apparent throughout the SDK. Here's a description of the pseudo-neo-post-Hungarian notation we use. Of course, you're welcome to code however you like. If you feel strongly that we should change our internal coding standards, please post your requests at comp.sys.programmer.better.things.to.do.with.your.time, and we'll carefully consider them before not making any changes.
62 |
63 | ### Coding Conventions
64 |
65 | | Type | Suffix | Example |
66 | | ------------------------------------------------ | -------- | ---------------- |
67 | | Handle | `H` | `fooH` |
68 | | pointer (to) | `P` | `fooP` |
69 | | Boolean | `B` | `visibleB` |
70 | | Float | `F` | `degreesF` |
71 | | Long | `L` | `offsetL` |
72 | | unsigned long | `Lu` | `countLu` |
73 | | short | `S` | `indexS` |
74 | | char | `C` | `digitC` |
75 | | unsigned char | `Cu` | `redCu` |
76 | | function pointer | `\_func` | `sample_func` |
77 | | time value | `T` | `durationT` |
78 | | `char*` (NULL-terminated C string) | `Z` | `nameZ` |
79 | | rectangle | `R` | `boundsR` |
80 | | fixed rectangle | `FiR` | `boundsFiR` |
81 | | float rectangle | `FR` | `boundsFR` |
82 | | ratio | `Rt` | `scale_factorRt` |
83 | | `void*` | `PV` | `refconPV` |
84 | | optional parameter (must be passed, can be NULL) | `0` | `extra_flags0` |
85 |
--------------------------------------------------------------------------------
/docs/intro/apple-silicon-support.md:
--------------------------------------------------------------------------------
1 | # Apple Silicon Support
2 |
3 | Adobe now supports Apple Silicon effect plugins in some products running natively on Apple Silicon. For instance, After Effects effect plugins are also available in Adobe Premiere Pro and Adobe Media Encoder.
4 |
5 | Not all Adobe products have native Apple Silicon versions yet, but in those that do, only effect plugins with Apple Silicon implementations will be available. We recommend adding the Apple Silicon target soon in anticipation of rapid adoption of these new M1 machines.
6 |
7 | !!! note
8 | In order to build a Mac Universal binary, you will need Xcode 12.2 or greater.
9 |
10 | To learn more about Universal binaries, please visit [https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary](https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary)
11 |
12 | Loading plugins on macOS 15+ for debugging also requires an additional signing step. See [here](debugging-plug-ins.md#signing-requirments-and-loading-unsigned-plug-ins) for details.
13 |
14 | ---
15 |
16 | ## How to add Universal Binary Support for your Plugins
17 |
18 | 1. Open your plugins Xcode project in 12.2 or above and Xcode will automatically add an Apple Silicon target for you.
19 |
20 | 
21 | *Mac Universal Build*
22 |
23 | 1. Tell After Effects what the main entry point is for Apple Silicon builds.
24 |
25 | > * Find the .r resource file for your plugin.
26 | > * Add `CodeMacARM64 {"EffectMain"}` next to your existing Intel Mac entry point definition.
27 | > ```cpp
28 | > #if defined(AE_OS_MAC)
29 | > CodeMacARM64 {"EffectMain"},
30 | > CodeMacIntel64 {"EffectMain"},
31 | > #endif
32 | > ```
33 | > * If for some reason you need different entry points on x64 and ARM just provide a different entry point name and string.
34 |
35 | 3. Compile the Universal binary by building for the Any Mac (Apple Silicon, Intel) Target, or by using Product -> Archive.
36 |
37 | Assuming there are no compile time issues with the Apple Silicon build, you can now use the single Universal binary for both Intel and Apple Silicon applications.
38 |
39 | ---
40 |
41 | ## Exception Behavior with Apple Silicon Across "C" Functions
42 |
43 | Extra care should be taken when using exceptions on Apple Silicon. In many environments throwing exceptions that propagate through traditional "C" functions worked fine. It was bad practice, with undefined behavior, but generally "worked".
44 |
45 | On Apple Silicon, rather than undefined behavior the ABI has changed so terminate() is called when this occurs.
46 |
47 | Since the main entry point of a plugin is always an extern "C" calling convention, this code should be wrapped in a try/catch block to prevent program termination. For example:
48 |
49 | ```cpp
50 | PF_Err EffectMain ( PF_Cmd cmd,
51 | PF_InData *in_data,
52 | PF_OutData *out_data,
53 | PF_ParamDef *params[],
54 | PF_LayerDef *output )
55 | {
56 | try
57 | {
58 | /* Your code here */
59 | }
60 | catch
61 | {
62 | /* return most appropriate PF_Err */
63 | }
64 | }
65 | ```
66 |
--------------------------------------------------------------------------------
/docs/intro/compatibility-across-multiple-versions.md:
--------------------------------------------------------------------------------
1 | # Compatibility Across Multiple Versions?
2 |
3 | Generally, you should compile your plug-ins with the latest After Effects SDK headers. This makes the latest suites and API functionality available to your plug-ins. When a new version of After Effects is released, you generally will not need to provide a new version unless you wish to take advantage of new functionality exposed through the new SDK. However, you should always test your plug-in in new versions of After Effects before claiming compatibility with new versions.
4 |
5 | You should test your plug-in thoroughly in each version of After Effects supported by your plug-in. If you need to add a conditional block of code to be run only in specific versions of After Effects, you can always check the API version in [PF_InData](../effect-basics/PF_InData.md).version for effects, or in the major and minor_versionL passed into your AEGP in the [Entry Point](../aegps/implementation.md#entry-point).
6 |
7 | For even more precise version checking, a plug-in can run a script using `AEGP_ExecuteScript` ([AEGP_UtilitySuite6](../aegps/aegp-suites.md#aegp_utilitysuite6)), querying one of the following attributes:
8 |
9 | ```cpp
10 | app.version - e.g. 11.0.1x12
11 | app.buildNumber - e.g. 12.
12 | ```
13 |
14 | ---
15 |
16 | ## API Versions
17 |
18 | | Release | Effect API Version | AEGP API Version |
19 | | ---------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------- |
20 | | 22.0 | 13.27 | |
21 | | 18.2 | 13.25 | |
22 | | 18.0 | 13.24 | |
23 | | 17.7 | 13.23 | |
24 | | 17.6 | 13.22 | |
25 | | 17.5 | 13.21 | |
26 | | 17.3 | 13.20 | |
27 | | 17.1 | 13.19 | |
28 | | 17.0 | 13.18 | |
29 | | 16.1 | 13.17 | |
30 | | 16.0 | 13.16 | |
31 | | 15.0 | 13.15 | |
32 | | CC 2017.1 (14.2) | 13.14 | |
33 | | CC 2017 (14.0) | 13.13 | 114.0 |
34 | | CC 2015.3 (13.8) | 13.11 | 113.8 |
35 | | CC 2015 (13.7) | 13.10 | 113.7 |
36 | | CC 2015 (13.6) | 13.10 | |
37 | | CC 2015 (13.5, 13.5.1) | 13.9 | 113.5 |
38 | | CC 2014 (13.0-13.2) | 13.7 | 113 |
39 | | CC (12.2) | 13.6 | 112.2 |
40 | | CC (12.1) | 13.5 | 112.1 |
41 | | CC (12.0) | 13.4 | 112.0 |
42 | | CS6.0.1 (11.0.1) | 13.3 | 111.0 |
43 | | CS6 (11.0) | 13.2 | 111.0 |
44 | | CS5.5 (10.5) | 13.1 | 17.0 |
45 | | CS5 (10.0) | 13.0 | 17.0 |
46 | | CS4 (9.0) | 12.14 | 16.24 |
47 | | CS3 (8.0) | 12.13 | 16.24 |
48 | | 7.0 | 12.12 | |
49 | | 6.5, 6.0 | 12.10 (Check for the presence of updated AEGP suites, should you need to differentiate between 6.0 and 6.5.) | |
50 | | 5.0 | 12.5 | |
51 | | 4.1 | 12.2 | |
52 | | 3.1 | 11.6 | |
53 |
--------------------------------------------------------------------------------
/docs/intro/debugging-plug-ins.md:
--------------------------------------------------------------------------------
1 | # Debugging Plug-ins
2 |
3 | The best way to learn the interaction(s) between After Effects and plug-ins is running the samples in your debugger. Spending some quality time in your compiler's debugger, and a sample project that closely resembles your plug-in, can really pay off.
4 |
5 | Once you've got the plug-in building directly into the plug-ins folder as explained above, here's how to specify After Effects as the application to run during debug sessions:
6 |
7 | ### Windows
8 |
9 | 1. In the Visual Studio solution, in the Solution Explorer panel, choose the project you want to debug
10 | 2. Right-click it and choose Set as StartUp Project
11 | 3. Right-click it again and choose Properties
12 | 4. In Configuration Properties > Debugging > Command, provide the path to the executable file of the host application the plug-ins will be running in (this may be After Effects or Premiere Pro)
13 | 5. From there you can either hit the Play button, or you can launch the application and later at any point choose Debug > Attach to Process...
14 |
15 | ### macOS
16 |
17 | 1. In Xcode, in the Project Navigator, choose the xcodeproj you want to debug
18 | 2. Choose Product > Scheme > Edit Scheme...
19 | 3. Under Run, in the Info tab, for Executable, choose the host application the plug-ins will be running in (this may be After Effects or Premiere Pro)
20 | 4. From there you can either hit the Play button to build and run the current scheme, or you can launch the application and later at any point choose Debug > Attach to Process.
21 |
22 | #### Signing requirments and loading unsigned plug-ins
23 |
24 | macOS versions 15+ prevent the loading of unsigned plugins. During development, you can avoid this difficulty by adding ad-hoc signing as a custom build step.
25 |
26 | `codesign --force --deep --sign - /path/to/plugin.dylib`
27 |
28 | Note: Yes, that trailing '-' after '--sign' is important.
29 |
30 | When you are ready to release, ensure that you do _not_ make changes to the plug-in package after signing, as this will invalidate said signing and prevent the plug-in from loading.
31 |
32 | ---
33 |
34 | ## Deleting Preferences
35 |
36 | During the course of developing a plug-in, your plug-in may pass settings information to After Effects, which is then stored in its preferences file.
37 |
38 | You may delete the preferences and restart After Effects with a clean slate by holding down Ctrl-Alt-Shift / Cmd-Opt-Shift during launch.
39 |
40 | On Windows, the preferences are stored here: `[user folder]\AppData\Roaming\Adobe\After Effects\[version]\Adobe After Effects [version]-x64 Prefs.txt`
41 |
42 | On macOS, they are stored here: `~/Library/Preferences/Adobe/After Effects/[version]/Adobe After Effects [version]-x64 Prefs`
43 |
--------------------------------------------------------------------------------
/docs/intro/exceptions.md:
--------------------------------------------------------------------------------
1 | # Exceptions
2 |
3 | Handle all exceptions generated by your plug-in's code, *within* your plug-in. Pass those which didn't originate in your plug-in's code to After Effects.
4 |
5 | After Effects' APIs are designed for plug-ins written in C, and don't expect exceptions. After Effects will crash immediately if one is thrown from within a plug-in.
6 |
7 | The effect samples use a firewall around the switch statement in the `main()` function, and the AEGPs wrap their function hooks in try/catch blocks.
8 |
--------------------------------------------------------------------------------
/docs/intro/how-to-start-creating-plug-ins.md:
--------------------------------------------------------------------------------
1 | # How To Start Creating Plug-ins
2 |
3 | ## Play!
4 |
5 | Before you write a line of code, Spend some significant time playing with After Effects, and with the [Sample Projects](sample-projects.md). Build the plug-ins into the right folder. Set lots of breakpoints, read the amusing and informative comments.
6 |
7 | See a quickstart video on building an effect (on macOS): [quickstart video](https://assets.adobe.com/public/08c43fb7-4633-4007-5201-b3b77405d770?scid=social_20180227_75678337)
8 |
9 | ---
10 |
11 | ## Plan!
12 |
13 | Be clear on what your plug-in will attempt to do.
14 |
15 | ---
16 |
17 | ## Hack!
18 |
19 | After experimenting with the samples, find one that does something *like* what you want to do. The temptation to start from scratch may be strong; fight it! For effects, use the Skeleton template project. Avoid the headache of reconstructing projects (including the troublesome custom build steps for Windows PiPL resource generation) by grafting your code into an existing project.
20 |
21 | ---
22 |
23 | ## Steal!
24 |
25 | To make the Skeleton sample your own, copy the entire \\Skeleton directory, renaming it to (for example) \\WhizBang. Using your text editor of choice, search \\WhizBang\*.\* (yes, that includes .NET and Xcode project files) for occurrences of Skeleton and SKELETON, and replace them with WhizBang and WHIZBANG.
26 |
27 | You now have a compiling and running plug-in that responds to common commands, handles 8 and 16-bpc color, uses our AEGP_SuiteHandler utility code, and responds to 3D light and camera information. There, was that so hard?
28 |
29 | AEGP developers will do well to start with Projector (for After Effects project creation support), Easy Cheese for a keyframe assistant, IO for media file format support, and Persisto for a simple menu command and working with preferences.
30 |
31 | ---
32 |
33 | ## Test!
34 |
35 | If only for testing convenience, you should have a project saved with your effect applied, and all its parameters keyframed to strange values. Between these projects which stress your plug-in, and the tools provided by your development environment, you're well on your way to shipping some tested code.
36 |
37 | ---
38 |
39 | ## Blame!
40 |
41 | If you run into behavior that seems wrong, see if you can reproduce the behavior using one of the unmodified sample projects. This can save you a lot of time, if you can determine whether the bug behavior was introduced by your modifications, or was already there to begin with.
42 |
43 | ---
44 |
45 | ## Developers Matter
46 |
47 | Third party developers drive API and SDK improvement and expansion. Your products enable After Effects to do things we'd never considered. Your efforts make After Effects better; keep it up!
48 |
49 | We work hard on the SDK, and welcome your comments and feedback. Almost every change we make to the API is suggested by developers like you. [Give us feedback](https://community.adobe.com/t5/after-effects/bd-p/after-effects?page=1&sort=latest_replies&filter=all&topics=label-sdkcom)
50 |
--------------------------------------------------------------------------------
/docs/intro/localization.md:
--------------------------------------------------------------------------------
1 | # Localization
2 |
3 | Starting in CC, PF App Suite ([Useful Utility Functions](../effect-details/useful-utility-functions.md)) adds `PF_AppGetLanguage()` to query the current language so that a plug-in can use the correct language string.
4 |
5 | When passing strings to AE, some parts of the API accept Unicode. In other areas, for example when specifying effect parameter names during `PF_Cmd_PARAM_SETUP`, you'll need to pass the names in a char string. For these non-Unicode strings, AE interprets strings as being multi-byte encoded using the application's current locale. To build these strings, on Windows you can use the `WideCharToMultiByte()` function, specifying `CP_OEMCP` as the first argument. On macOS, use the encoding returned by `GetApplicationTextEncoding()`.
6 |
7 | Testing with different languages in AE doesn't require an OS reinstallation, but it does require a reinstallation of AE:
8 |
9 | ### Windows
10 |
11 | - Change the system locale to the targeted language (control panel > region and language > administrative tab > change system locale)
12 | - Restart machine
13 | - Install AE in the according language.
14 |
15 | ### MacOS
16 |
17 | - Set targeted language to the primary language in the preferred language list
18 | - Install AE in the according language.
19 |
--------------------------------------------------------------------------------
/docs/intro/next-steps.md:
--------------------------------------------------------------------------------
1 | # Next Steps
2 |
3 | You now have an understanding of what plug-ins are, what they can do, and how After Effects communicates with them.
4 |
5 | Next, we will cover the [basics of effects plug-ins](../effect-basics/effect-basics.md).
6 |
--------------------------------------------------------------------------------
/docs/intro/other-integration-possibilities.md:
--------------------------------------------------------------------------------
1 | # Other Integration Possibilities
2 |
3 | Although this SDK describes the majority of integration possibilities with After Effects, there are other possibilities not to be overlooked.
4 |
5 | ---
6 |
7 | ## Scripting
8 |
9 | Scripting is a relatively nimble and lightweight means to perform automated tasks with After Effects. ScriptUI is one way you can provide UI integration with custom dialogs and panels (see [HTML5 Panels](#html5-panels) too). And scripting may be used in tandem with plug-in development, in the cases where a certain function is made available via scripting and not via the C APIs described in this document.
10 |
11 | Scripting in After Effects is done using ExtendScript, based on JavaScript. After Effects includes the ExtendScript ToolKit, a convenient interface for creating and testing your own scripts. Scripts may be compiled into .jsxbin binary files, to protect intellectual property.
12 |
13 | You can access the After Effects Scripting Guide, and find a link to the scripting forums, on the Adobe I/O website at: [https://www.adobe.io/apis/creativecloud/aftereffects.html](https://www.adobe.io/apis/creativecloud/aftereffects.html)
14 |
15 | After Effects can be driven by executing scripts from the commandline. In your script, you can open the project and run script actions on it. So for example, you can execute the following statement to run a script from the command line directly:
16 |
17 | ```sh
18 | AfterFX -s "app.quit()"
19 | ```
20 |
21 | Or you can execute this statement to run a .jsx script that includes a quit at the end:
22 |
23 | ```sh
24 | AfterFX -r path_to_jsx_script
25 | ```
26 |
27 | On Windows, AfterFX.com is the way to get feedback to the console, because AfterFX.com is a command line application.
28 |
29 | ---
30 |
31 | ## HTML5 Panels
32 |
33 | In CC 2014 and later, After Effects supports HTML5 panels. They are accessed in After Effects from Window > Extensions > (your panel name). Panels can be resized and docked just like any other panel in After Effects. Panels are built using HTML5, After Effects Scripting, and JavaScript. You may download the After Effects Panel SDK from the the Adobe I/O website at: [https://www.adobe.io/apis/creativecloud/aftereffects.html](https://www.adobe.io/apis/creativecloud/aftereffects.html)
34 |
35 | ---
36 |
37 | ## AERender
38 |
39 | Closely coupled with scripting is the command line interface offered by aerender. aerender is primarily suited to allow automated renders, but can be used to execute any sequence of scripting commands from the command line. An overview is available in the After Effects help documents here: [https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
40 |
41 | ---
42 |
43 | ## Premiere Pro Importers
44 |
45 | Premiere Pro importers provide support for importing media into applications across most applications in the Adobe Creative Cloud, including Premiere Pro, Media Encoder, Prelude, and Audition. Because of this broader compatibility, unless you need very specific integration with After Effects only available via the AEIO API in this SDK, we recommend developing a Premiere Pro importer. The Premiere Pro SDK is available at: [https://www.adobe.io/apis/creativecloud/premierepro.html](https://www.adobe.io/apis/creativecloud/premierepro.html)
46 |
47 | One advantage of MediaCore importer plug-ins over AEIOs is its priority system: The highest priority importer gets first crack at importing a file, and if the particular imported file isn't supported, the next-highest priority importer will then have the opportunity to try importing it, and so on.
48 |
49 | ---
50 |
51 | ## Mercury Transmit
52 |
53 | Mercury Transmit plug-ins are used for sending video to output hardware for broadcast-quality monitoring. Transmitters are supported across most applications in the Adobe Creative Cloud, including Premiere Pro, After Effects, Prelude, and Character Animator. The Mercury Transmit API is documented in the Premiere Pro SDK, available at: [https://www.adobe.io/apis/creativecloud/premierepro.html](https://www.adobe.io/apis/creativecloud/premierepro.html)
54 |
--------------------------------------------------------------------------------
/docs/intro/sdk-audience.md:
--------------------------------------------------------------------------------
1 | # SDK Audience
2 |
3 | You must be a proficient C/C++ programmer to write After Effects plug-ins. While we'll help with issues specific to the After Effects API, we can't help you learn your IDE or basic programming concepts.
4 |
5 | This SDK guide assumes you understand After Effects from a user's perspective, and basic motion graphics terminology. If you don't, get the [Adobe After Effects Classroom in a Book](http://www.adobepress.com/store/adobe-after-effects-cc-classroom-in-a-book-2017-release-9780134665320), or any of the other fine instructional books on the market. It will help you understand necessary
6 |
7 | topics such as alpha channels, pixel aspect ratio, interlacing, color spaces, and more for After Effects.
8 |
9 | ---
10 |
11 | ## Development Requirements
12 |
13 | The system requirements for After Effects are here: [https://helpx.adobe.com/after-effects/system-requirements.html](https://helpx.adobe.com/after-effects/system-requirements.html)
14 |
15 | The SDK samples have been tested on Xcode 11.3.1 and Xcode 12.4 (for universal binary support with Apple Silicon) on macOS 10.15/11.0, and Microsoft Visual Studio 2019 on Windows 10.
16 |
--------------------------------------------------------------------------------
/docs/intro/symbol-export.md:
--------------------------------------------------------------------------------
1 | # Exporting Symbols in Effects
2 |
3 | The After Effects team recently became aware of an issue with conflicting symbols that violate the C++ language One Definition Rule (ODR).
4 |
5 | In early 2021, the version of the Boost library used by After Effects was upgraded to 1.74. Over the last few months we've identified a number of plugins that are also using Boost but are exporting symbols in such a way that After Effects or the plugin may end up calling the incorrect version of Boost leading to hangs and crashes for users. We also identified a number of the AE SDK samples were setup to export all symbols by default which may have been contributing to the problem, assuming they were used as the starting point for other plugins. These have been fixed as part of the March 2021 SDK.
6 |
7 | **The only symbol that After Effects requires to be exported is the entry point of the plugin.**
8 |
9 | An example can be found in the SDK samples in entry.h:
10 |
11 | ```cpp
12 | #ifdef AE_OS_WIN
13 | #define DllExport __declspec( dllexport )
14 | #elif defined AE_OS_MAC
15 | #define DllExport __attribute__ ((visibility ("default")))
16 | #endif
17 | ```
18 |
19 | and then this is applied to the entry point function, for example:
20 |
21 | ```cpp
22 | extern "C" DllExport
23 | PF_Err PluginDataEntryFunction(
24 | PF_PluginDataPtr inPtr,
25 | PF_PluginDataCB inPluginDataCallBackPtr,
26 | SPBasicSuite* inSPBasicSuitePtr,
27 | const char* inHostName,
28 | const char* inHostVersion)
29 | {
30 | PF_Err result = PF_Err_INVALID_CALLBACK;
31 |
32 | result = PF_REGISTER_EFFECT(
33 | inPtr,
34 | inPluginDataCallBackPtr,
35 | "ColorGrid", // Name
36 | "ADBE ColorGrid", // Match Name
37 | "Sample Plug-ins", // Category
38 | AE_RESERVED_INFO); // Reserved Info
39 |
40 | return result;
41 | }
42 | ```
43 |
44 | ---
45 |
46 | ## Disabling Xcode Symbol Export
47 |
48 | To disable symbol export in Xcode:
49 |
50 | 1. Find the **Apple Clang - Code Generation** section in the **Build** settings for your project.
51 | 2. Set the **Symbols Hidden By Default** to **YES**
52 |
53 | 
54 | *Apple Clang Symbols*
55 |
56 | For any specific symbols that must be made public, use the `__attribute__((visibility("default")))` in code.
57 |
58 | More information can be found in Apple's Xcode documentation [https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6](https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6) (excerpt below):
59 |
60 | > Symbols Hidden by Default (GCC_SYMBOLS_PRIVATE_EXTERN)
61 | >
62 | > When enabled, all symbols are declared private extern unless explicitly marked to be exported using __attribute__((visibility("default"))) in code. If not enabled, all symbols are exported unless explicitly marked as private extern.
63 |
64 | ---
65 |
66 | ## Disabling Visual Studio Export
67 |
68 | By default, builds from Visual Studio automatically disable symbol exports. To export symbols, you must either supply a module definition file or set the \_\_declspec(dllexport) keyword in the functions definition.
69 |
70 | More information can be found in Microsoft's Visual Studio documentation [https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll?view=msvc-160](https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll?view=msvc-160) (excerpt below):
71 |
72 | > You can export functions from a DLL using two methods:
73 | >
74 | > 1. Create a module definition (.def) file and use the .def file when building the DLL. Use this approach if you want to export functions from your DLL by ordinal rather than by name.
75 | > 2. Use the keyword __declspec(dllexport) in the function's definition.
76 | >
77 | > When exporting functions with either method, make sure to use the __stdcall calling convention.
78 |
--------------------------------------------------------------------------------
/docs/intro/third-party-plug-in-hosts.md:
--------------------------------------------------------------------------------
1 | # Third-party Plug-in Hosts?
2 |
3 | Some developers are wary of using each After Effects release's new API features, to maintain compatibility with hosts with partial implementations. You can distinguish between host applications by checking [PF_InData](../effect-basics/PF_InData.md)>appl_id. After Effects uses the appl_id 'FXTC'.
4 |
5 | Premiere Pro uses 'PrMr'. As of this writing, no third party hosts support SmartFX, or our AEGP functions.
6 |
7 | Also, see the [Premiere Pro & Other Hosts](../ppro/ppro.md) section.
8 |
--------------------------------------------------------------------------------
/docs/intro/what-can-i-do.md:
--------------------------------------------------------------------------------
1 | # What Can I Do With This SDK?
2 |
3 | This SDK describes the Application Programming Interface (API) that developers use to build plug-ins. These plug-ins can extend the capabilities of After Effects and other applications that support the After Effects API. Plug-ins may also be used to bridge the gap between After Effects and another application.
4 |
5 | ---
6 |
7 | ## What Plug-Ins Can I Build With This SDK?
8 |
9 | *Effect plug-ins* can be applied to video or audio in a composition, to process video and/or audio data. Some examples of built-in effects are Brightness and Contast, Hue/Saturation, Gaussian Blur, and Warp Stabilizer. Effect plug-ins can provide a set of parameter controls for the user to fine-tune the effect. These parameter values can vary over time, and effects may use other layers and parameters at different times to calculate the output. It's often thought that all plug-ins are effects. But effects are just one type of plug-in used by After Effects.
10 |
11 | See a quickstart video on building an effect (on macOS): [adobe.ly/2sjMDwM](https://adobe.ly/2sjMDwM)
12 |
13 | *After Effects General Plug-ins (AEGPs)* can read and modify nearly every element of After Effects projects and preferences. They can add menu items, 'hook' (register themselves to receive) and trigger After Effects' internal commands, and add new panels that dock and resize within the After Effects UI. They can work with markers and keyframes, and manage the render queue. They can even run scripts. Some examples of built-in AEGPs are the AAF importer, and the SWF exporter. Automatic Duck Pro Import AE is another well-known AEGP.
14 |
15 | *After Effects Input/Output (AEIO) plug-ins* provide support for new media file types. Unless you need a custom setup dialog to specify interpretation settings, the [Premiere Pro Importers](other-integration-possibilities.md#premiere-pro-importers) API provides similar functionality, and is preferable in many cases. AEIOs use the AEGP API along with certain APIs specific to AEIOs. While After Effects still supports Photoshop format plug-ins and filters, as well as Foreign Project Format (FPF) plug-ins, these APIs have been long deprecated in favor of the AEIO API.
16 |
17 | *BlitHook* plug-ins output video to external hardware for broadcast quality monitoring and playback to tape. The EMP sample project provides a starting point. In After Effects CC 2014 and later, [Mercury Transmit](other-integration-possibilities.md#mercury-transmit) is the recommended API.
18 |
19 | *Artisans* provide rendered output of 3D layers, taking over 3D rendering from After Effects (which still handles all rendering of 2D layers). Artisans use the AEGP API along with certain APIs specific to Artisans.
20 |
21 | Didn't see the type of integration you need described above? After Effects is very flexible, and there are several other ways to integrate with After Effects. See: [Other Integration Possibilities](other-integration-possibilities.md).
22 |
23 | ---
24 |
25 | ## Where Do Plug-ins Appear In After Effects?
26 |
27 | Effects plug-ins appear in both the *Effect* menu and the Effects & Presets panel, in the effect category specified in their PiPL. Once they're applied, the effect's parameter controls (sliders, pop-ups, etc.) appear in the Effect Controls panel (ECP).
28 |
29 | After Effects General Plug-ins (AEGPs) can add items to any After Effects menu, and additional panels listed in the Window menu. These menu items are indistinguishable from After Effects' own menu items.
30 |
31 | [AEIOs](../aeios/aeios.md) and Photoshop Format plug-ins can appear in the *File > Import* menu, or in the *Import File* dialog in the *Files of type* drop-down, depending on the type of importer. AEIOs and Format plug-ins can also appear as available output formats in the render queue.
32 |
33 | BlitHook plug-ins are automatically loaded and used by AE, but do not appear in any menu or dialog. The plug-in may optionally provide a menu item that opens it's own custom settings dialog. It would register and update the menu item using the AEGP API.
34 |
35 | It can registered to be called by After Effects to update the menu with `AEGP_RegisterUpdateMenuHook()`, and it can dim/activate the menu item using `AEGP_EnableCommand()`/`DisableCommand()`.
36 |
37 | Artisans appear in the *Rendering Plug-in* drop-down in the *Advanced* tab of the *Composition Settings* dialog.
38 |
39 | ---
40 |
41 | ## How Does After Effects Interact With Plug-ins?
42 |
43 | Plug-ins, written in C or C++, are bundle packages on macOS and DLLs on Windows. They must contain a Plug-in Property List ([PiPL Resources](pipl-resources.md)) resource on both platforms. The plug-ins must be located in one of a few specific folders in order to be loaded and used by After Effects.
44 |
45 | For effects plug-ins, After Effects sends command selectors (and relevant information) to the plug-in [Entry Point](../effect-basics/entry-point.md) designated in the effects' [PiPL Resources](pipl-resources.md) resource. Selectors are sent in response to actions the user takes—applying the effect, changing parameters, scrubbing through frames in the timeline, and rendering all prompt different sequences of selectors.
46 |
47 | After Effects creates multiple instances of effects, with settings and input data unique to each sequence. All instances share the same global data, and can share data between all frames within their sequence. After Effects doesn't process all image data as soon as the user applies an effect; it invokes effects only when their output is required.
48 |
49 | After Effects General Plug-ins (AEGPs) have their entry point function called during application launch, and register for whatever messaging they need at that time. Further calls to the AEGP are initiated by user actions, as part of the plug-in's response to menu commands or UI events. Depending on their features, plug-ins may need to respond to OS-specific entry points as well, for UI work and thread management.
50 |
51 | For BlitHook plug-ins, frames are pushed as they're displayed in the Composition panel. Users can initiate a RAM preview on an area of the timeline so that it is rendered to RAM, and then it all gets played out at full speed.
52 |
53 | ---
54 |
55 | ## SDK Contents
56 |
57 | The SDK contains headers defining the After Effects APIs, sample projects demonstrating integration features, and this SDK Guide.
58 |
59 | They are compiled with the SDK header files, which expose various After Effects functionality to be used by the plug-in.
60 |
--------------------------------------------------------------------------------
/docs/intro/where-installers-should-put-plug-ins.md:
--------------------------------------------------------------------------------
1 | # Where Installers Should Put Plug-ins
2 |
3 | Installing your plug-ins in the common location will allow them to be loaded by Premiere Pro, if installed.
4 |
5 | On Windows, the common plug-ins folder can be found (as an explicit path) in the following registry entry: `HKLM\SOFTWARE\Adobe\After Effects\[version]\CommonPluginInstallPath`
6 |
7 | On Mac, the common plug-ins folder is at: `/Library/Application Support/Adobe/Common/Plug-ins/[version]/MediaCore`
8 |
9 | Version is locked at 7.0 for all CC versions, or CSx for earlier versions. For example: `/Library/Application Support/Adobe/Common/Plug-ins/7.0/MediaCore/`
10 |
11 | Do not use macOS aliases or Windows shortcuts, as these are not traversed by Premiere Pro.
12 |
13 | ---
14 |
15 | ## Do I Have To Install The Plug-ins To The Common Folder?
16 |
17 | You may have good reason to install your plug-in for only After Effects, for example, if your plug-in depends on suites and functionality not available in Premiere Pro. We strongly recommend that you use the common folder whenever possible, but for certain cases, the AE-specific plug-in folder is still available.
18 |
19 | On Windows, the app-specific plug-ins folder can be found (as an explicit path) in the following registry entry: `\\HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\After Effects\(version)\PluginInstallPath`
20 |
21 | On macOS, the app-specific plug-ins folder is at: `/Applications/Adobe After Effects [version]/Plug-ins/`
22 |
23 | When launched, After Effects recursively descends 10 levels deep into subdirectories of its path. macOS aliases are traversed, but Windows shortcuts are not. Directories terminated by parentheses or preceded by the symbols ¬ (macOS) or ~ (Windows) are not scanned.
24 |
25 | Try as you might to build a fence between AE and Premiere Pro, users will still find ways to get across using our lovely integration goodness - Your effects will still be available to Premiere Pro users who create a dynamically linked AE composition with your effect, and put it in a Premiere Pro sequence.
26 |
--------------------------------------------------------------------------------
/docs/ppro/basic-host-differences.md:
--------------------------------------------------------------------------------
1 | # Basic Host Differences
2 |
3 | We've tried to provide robust compatibility for After Effects effect plug-ins in Premiere Pro.
4 |
5 | There are underlying differences in the render pipeline that lead to differences, and we realize the API implementation may not be perfect.
6 |
7 | Below is an overview of some differences the plug-in will encounter when running in Premiere Pro.
8 |
9 | ---
10 |
11 | ## Time Values
12 |
13 | Premiere Pro uses slightly different time values in PF_InData. For example in CS4:
14 |
15 | Rendering in NTSC, time_scale is 60000, time_step is 1001, field gives field order (in After Effects, for field rendering, scale is 2997, step is 50, or for progressive rendering, scale is 2997, step is 100).
16 |
17 | Rendering in PAL, time_scale is 50, time_step is 1, field gives field order (in After Effects, for field rendering, scale is 3200, step is 64, or for progressive rendering, scale is 3200, step is 128).
18 |
19 | It's the ratio of time-related values that produces the time value, not specifically the time_scale value. It's possible Premiere Pro will use different time_scales in the future, so please don't hard code. Just be aware that it does not necessarily use the exact same values as After Effects.
20 |
21 | ---
22 |
23 | ## Rendering Frames
24 |
25 | Premiere is optimized for responsive editing. When scrubbing in the timeline, and changing effect parameters, Premiere will immediately request a low-quality render for immediate display, followed by a high-quality render. So the effect may receive two requests for the same effective time, one at a low resolution, low bit-depth, followed by one at full-resolution, full bit-depth. The resolution requested for each render with take into account the Playback and Paused Resolution set in the Source and Program Monitors: The first request will be at the Playback Resolution, and the second request will be at the Paused Resolution.
26 |
27 | Premiere will also perform speculative rendering, to render a set of frames ahead in the timeline, so that if/when the editor starts playback, the initial frames will be ready. This means that when repositioning the time needle, or when changing effect parameters, Premiere will ask the effect to render a set of frames ahead of the current time. If the frames have previously been rendered and cached, the effect will not see these render requests because the cached frames will be used.
28 |
29 | When rendering frames in Premiere-native pixel formats, Premiere will send PF_Cmd_RENDER once for each field, rather than for each frame. The `PF_InData->field` will indicate which field is being rendered, the `PF_LayerDef->height` will be half of the frame height, and the `PF_LayerDef->rowbytes` will be double the normal value.
30 |
31 | ---
32 |
33 | ## Render Order
34 |
35 | Premiere Pro was built to provide real-time playback of footage with effects wherever possible. The render scheduling is much more aggressive and multithreaded rendering is a basic requirement. This is quite different than After Effects, where users are building layers upon layers of effects and more willing to wait for a RAM preview.
36 |
37 | Multithreaded rendering in Premiere applies to AE effects too. When rendering an AE effect, the request from Premiere passes through a critical section which is used for all commands, except those relating to arbitrary data. The critical section prevents two threads from calling the same instance of the effect at the same time. However, Premiere creates multiple instances of the effect, which can be called concurrently from separate threads.
38 |
39 | Therefore, an effect should not expect to receive render requests in order of increasing time. Also, effects should not depend on static, non-constant variables.
40 |
41 | ---
42 |
43 | ## Frame Dimensions
44 |
45 | Differences between source footage and the project/composition are handled differently.
46 |
47 | For example, in CS4, when importing an NTSC clip in a PAL sequence, `PF_InData>width,height` are `(598,480)` and `PF_InData->pixel_aspect_ratio` is `(768,702)`.
48 |
49 | In AE, `width,height` are `(720,480)` and `pixel_aspect_ratio` is `(10,11)`.
50 |
51 | ---
52 |
53 | ## PF_InData
54 |
55 | Premiere Pro handles field rendering differently than After Effects. While field rendering, `PF_InData>field` gives the current field being rendered, ignoring whether or not `PF_OutFlag_PIX_INDEPENDENT` flag was set.
56 |
57 | In Premiere Pro, effects receive the quality setting of the monitor window in [PF_InData>quality](../effect-basics/PF_InData.md#pf_indata-members). This differs from After Effects, where the source layer's quality setting is provided here.
58 |
59 | ---
60 |
61 | ## Parameter UI
62 |
63 | Premiere Pro does not honor the [PF_ParamFlag_START_COLLAPSED](../effect-basics/PF_ParamDef.md#parameter-flags) flag. Parameters are always initialized with their twirlies collapsed, and cannot be automatically twirled open by parameter supervision.
64 |
65 | Premiere Pro supports the macro `PF_ADD_FLOAT_EXPONENTIAL_SLIDER()`, which lets you define an exponent. Although this macro is newly added for the CC 2015 release 2 SDK, Premiere Pro has used this for some time in the Fast Color Corrector, in the Input Grey Level parameter. The exponent is used so that although the range is from 0.10 to 10, 1.0 is about in the middle of the slider. The exponent we used was 2.5. Typical values would be from 0.01 to 100.
66 |
67 | Starting in CC 2015, effects will not be sent `PF_Cmd_UPDATE_PARAMS_UI` or `PF_Event_DRAW` when the time needle is moved and there are no keyframes, unless the effect sets `PF_OutFlag_NON_PARAM_VARY`. Effects such as those that draw histograms in the Effect Controls panel will need to be aware of this optimization.
68 |
69 | ---
70 |
71 | ## Missing Suites
72 |
73 | Many suites supported by After Effects are not implemented in the Premiere Pro host. In several cases, even if a suite is missing in Premiere Pro, an equivalent macro function is available. Here are a few examples:
74 |
75 | | After Effects suite call | Premiere Pro equivalent function |
76 | | --------------------------------------- | -------------------------------- |
77 | | `WorldTransformSuite1()->copy()` | `PF_COPY()` |
78 | | `WorldTransformSuite1()->convolve()` | `in_data->utils->convolve()` |
79 | | `FillMatteSuite2()->fill()` | `PF_FILL()` |
80 | | `PF_PixelDataSuite1->get_pixel_data8()` | `PF_GET_PIXEL_DATA8()` |
81 |
82 | The sample projects demonstrate alternate ways of handling a missing suite, by checking for the host application and version. The Portable sample project demonstrates both host application and version checking.
83 |
84 | ---
85 |
86 | ## A Special Suite for AE Effects Running in Premiere Pro
87 |
88 | No AEGP calls are supported by Premiere Pro. However, there are some interesting parallels in the header PrSDKAESupport.h. For example, you can use the Utility Suite in that header to get the frame rate or field type of the source footage, or to get the speed applied to the clip.
89 |
90 | Note that other suites from the Premiere Pro SDK cannot be used in AE effects.
91 |
--------------------------------------------------------------------------------
/docs/ppro/bigger-differences.md:
--------------------------------------------------------------------------------
1 | # Bigger Differences
2 |
3 | As long as an effect only supports the basic ARGB_8u pixel format supported by After Effects, Premiere Pro will try to imitate the After Effects hosting behavior and hide various differences because of the different render pipeline architecture. But if an effect wants to support additional pixel formats, such as 32-bit RGB, be prepared to handle further divergent behavior.
4 |
5 | ---
6 |
7 | ## Pixel Formats
8 |
9 | Premiere Pro provides function suites for declaring support for pixel formats other than the 8-bit RGB format used by After Effects - ARGB_8u. These pixel formats include the Premiere Pro native 8-bit RGB format - BGRA_8u, as well as YUV, 32-bit formats, and more. For a more detailed discussion of the various pixel formats, see ["Pixel Formats and Colorspaces" from the Premiere Pro SDK Guide](http://ppro-plugin-sdk.aenhancers.com/universals/pixel-formats-and-color-spaces.html).
10 |
11 | Use the PF Pixel Format Suite (defined in PrAESDKSupport.h) to register for [PF_EffectWorld / PF_LayerDef](../effect-basics/PF_EffectWorld.md) in other pixel formats. Use the Premiere Pixel Format Suite (defined in the aptly-named PrSDKPixelFormatSuite.h) to get black and white values in those pixel formats.
12 |
13 | After Effects functions such as `PF_BLEND()` have not been enhanced to work with pixel formats beyond 8-bit RGB.
14 |
15 | ---
16 |
17 | ## 32-Bit Float Support
18 |
19 | Premiere Pro does not support After Effects 16-bit rendering or SmartFX. For 32-bit rendering in Premiere Pro, you'll need to declare support for one of the 32-bit pixel formats (see previous section), and then implement 32-bit rendering for `PF_Cmd_RENDER`. You can support multiple render depths this way. See the SDK Noise sample project for an example.
20 |
21 | Depending on the clip(s) to which an effect is applied, 32-bit processing is not always necessary to preserve the quality of the source input. But there are settings to force 32-bit rendering, to give effects processing finer granularity and more headroom, if desired. Go to Settings>Sequence Settings> Video Previews>Maximum Bit Depth, to control previewing from the timeline. For export to file, use Export Settings>Video>Basic Settings>Render at Maximum Depth.
22 |
23 | ---
24 |
25 | ## PF_CHECKOUT_PARAM and Pixel Formats
26 |
27 | Before CS6, `PF_CHECKOUT_PARAM()` only returned 8-bit ARGB buffers, regardless of the pixel format currently being used for rendering. Starting in CS6, an effect can opt in to get frames in the same format as the render request, whether it is 32-bit float, YUV, etc.
28 |
29 | Plug-ins may request this behavior, but existing plug-ins will continue working receiving 8-bit ARGB frames. The call is EffectWantsCheckedOutFramesToMatch RenderPixelFormat(), in the PF Utility Suite, defined in PrSDKAESupport.h. The call should be made on `PF_Cmd_GLOBAL_SETUP`, the same selector where an effect would already advertise support beyond 8-bit RGB using `AddSupportedPixelFormat()`.
30 |
--------------------------------------------------------------------------------
/docs/ppro/multithreading.md:
--------------------------------------------------------------------------------
1 | # Multithreading
2 |
3 | You may have noticed this flag: `PF_OutFlag2_PPRO_DO_NOT_CLONE_SEQUENCE_DATA_FOR_RENDER`. We advise against setting this flag, as it has been found to cause parameter UI problems.
4 |
--------------------------------------------------------------------------------
/docs/ppro/other-hosts.md:
--------------------------------------------------------------------------------
1 | # Other Hosts
2 |
3 | For third-party hosts, the Adobe policy remains:
4 |
5 | !!! quote
6 | Adobe neither supports nor recommends the creation of Adobe-compatible third-party hosts. While it may be possible to create a partially functional host by reverse engineering from the plug-in API specification, we do not recommend it and will not support you in doing so.
7 |
8 | ---
9 |
10 | ## Reality Sandwich
11 |
12 | We realize that, for developers like you, one good way to grow your market is to ensure that your plug-ins work in as many hosts as possible.
13 |
14 | Our SmartFX API has created quite a bit of distance between the After Effects API and the implementations available in the rest of the plug-in hosting world.
15 |
16 | We will do what we can to help the other hosts support newer features. If you encounter problems in third party hosts, please refer them to us if they need assistance.
17 |
--------------------------------------------------------------------------------
/docs/ppro/plug-in-installation.md:
--------------------------------------------------------------------------------
1 | # Plug-in Installation
2 |
3 | Use the common plug-in folder as described here: [Where Installers Should Put Plug-ins](../intro/where-installers-should-put-plug-ins.md).
4 |
5 | If you try to install an effect plug-in only to the Premiere Pro plug-ins directory, you will be surprised to find that your effect is not rendered when you export to disk through Adobe Media Encoder, an entirely separate application.
6 |
7 | Oh, and you'll also miss out on project interchange and copy / paste between Premiere Pro and After Effects.
8 |
--------------------------------------------------------------------------------
/docs/ppro/plug-ins-reloaded.md:
--------------------------------------------------------------------------------
1 | # Plug-Ins... Reloaded
2 |
3 | On it's first launch, Premiere Pro loads all the plug-ins, reads the PiPL, and sends `PF_Cmd_GLOBAL_SETUP` to determine the plug-ins' capabilities. To save time on future application launches, it saves some of these capabilities in what we call the plug-in cache (the registry on Windows, a Property List file on macOS). The next time the application is launched, the cached information is used wherever possible, rather than loading the plug-ins.
4 |
5 | When debugging, you can always force a reload of all the plug-ins by holding down the Shift key when launching Premiere Pro.
6 |
7 | If your effect needs to be reloaded each time, there is a way to disable this caching. The plug-in can use the PF Cache On Load Suite in AE_CacheOnLoadSuite.h (from the [Premiere Pro SDK](http://ppro-plugin-sdk.aenhancers.com/) headers) to call `PF_SetNoCacheOnLoad()` during `PF_Cmd_GLOBAL_SETUP`. For the second parameter of that function, pass a non-zero value if you want your effect to show up in the UI. Pass zero if loading failed, but you still want Premiere Pro to attempt to load it again on the next relaunch.
8 |
9 | ---
10 |
11 | # Effects Presets
12 |
13 | Premiere Pro uses a different preset scheme than After Effects.
14 |
15 | From the Premiere Pro SDK Guide:
16 |
17 | Effect presets appear in the Presets bin in the Effects panel, and can be applied just like Effects with specific parameter settings and keyframes. Effect presets can be created as follows:
18 |
19 | 1. Apply a filter to a clip
20 | 2. Set the parameters of the filter, adding keyframes if desired
21 | 3. Right-click on the filter name in the Effect Controls panel, and select "Save Preset..."
22 | 4. Create preset bins if desired by right-clicking in the Effects panel and choosing "New Presets Bin"
23 | 5. Organize the presets in the preset folders
24 | 6. Select the bins and/or presets you wish to export, right-click, and choose "Export Preset"
25 |
26 | Presets should be installed in the Plug-ins directory. Once they are installed in that directory, they will be read-only, and the user will not be able to move them to a different folder or change their names. User-created presets will be modifiable.
27 |
28 | On Windows Vista, these are in the user's hidden AppData folder (e.g. `C:/Users/[user name]/AppData/Roaming/AdobePremiere Pro/[version]/Effect Presets and Custom Items.prfpset`).
29 |
30 | On macOS, they are in the user folder, at `~/Library/Application Support/Adobe/Premiere Pro/[version]/Effect Presets and Custom Items.prfpset`.
31 |
32 | ---
33 |
34 | # Custom ECW UI Over A Standard Data Type
35 |
36 | While this is logged as bug #1235407, there is a simple workaround: Create two separate parameters, and have the custom UI control the slider param using parameter supervision.
37 |
--------------------------------------------------------------------------------
/docs/ppro/ppro.md:
--------------------------------------------------------------------------------
1 | # Premiere Pro & Other Hosts
2 |
3 | Adobe Premiere Pro and Adobe Premiere Elements both support the After Effects effect API as described in chapters 2, 3, and 5.
4 |
5 | They offer a thorough host implementation, some the key omissions being 3D-related calls (auxiliary channel information, cameras and lights), 16-bit and SmartFX support, and other utility functions provided by After Effects' AEGP API.
6 |
7 | Both Premiere Pro and Premiere Elements set `PF_InData>appl_id` to 'PrMr'.
8 |
9 | In this chapter, we will describe the AE API support in Premiere Pro, but generally the same support exists in corresponding versions of Premiere Elements.
10 |
11 | If you need to distinguish between Premiere Pro and Premiere Elements, you may use the Premiere-specific App Info Suite, available from the [Premiere Pro SDK](http://ppro-plugin-sdk.aenhancers.com) headers.
12 |
13 | | Application Versions | PF_InData> version.major | PF_InData> version.minor |
14 | | -------------------------------------------- | ------------------------ | ------------------------ |
15 | | Premiere Pro CC through Premiere Pro CC 2019 | 13 | 4 |
16 | | Premiere Pro CS6 | 13 | 2 |
17 | | Premiere Pro CS5.5 | 13 | 1 |
18 | | Premiere Pro CS5, Premiere Elements 9 | 13 | 0 |
19 | | Premiere Pro CS4, Premiere Elements 8 | 12 | 5 |
20 | | Premiere Pro CS3, Premiere Elements 4 and 7 | 12 | 4 |
21 | | Premiere Pro 2.0, Premiere Elements 3 | 12 | 3 |
22 | | Premiere Pro 1.5, Premiere Elements 2 | 12 | 2 |
23 | | Premiere Pro 1.0, Premiere Elements 1 | 12 | 1 |
24 |
25 | Note that the versioning used by Premiere Pro and Premiere Elements does not mean that they support the same API features After Effects did at the same version. It is simply meant to distinguish from one version to the next.
26 |
--------------------------------------------------------------------------------
/docs/ppro/premiere-elements.md:
--------------------------------------------------------------------------------
1 | # Premiere Elements
2 |
3 | Premiere Elements (but not Premiere Pro) displays visual icons for each effect. You will need to provide icons for your effects, or else an empty black icon will be shown for your effects, or even worse behavior in Premiere Elements 8.
4 |
5 | The icons are 60x45 PNG files, and are placed here:
6 |
7 | `/[Program Files]/Adobe/Adobe Premiere Elements [version]/Plug-in/Common/Effect/Previews/`
8 |
9 | The filename should be the match name of the effect, which you specify in the [PiPL Resources](../intro/pipl-resources.md), prefixed with "AE." So if the match name was "MatchName", then the filename should be "AE.MatchName.png"
10 |
--------------------------------------------------------------------------------
/docs/ppro/unsupported-features.md:
--------------------------------------------------------------------------------
1 | # Unsupported Features
2 |
3 | Premiere Pro is currently known to not support the following features of the After Effects API:
4 |
5 | (If you would like a feature with a "-" bullet, please email [Premiere Pro API Engineering](mailto:bbb@adobe.com) with the feature request. Numbers preceded by an 'F' are feature request numbers, and the others are bug numbers)
6 |
7 | - F7233 - extent_hint support
8 | - F7835 - Multiple PiPLs in a single plug-in
9 | - F7836 - AEGP support
10 | - F7517 - Audio support - if a plug-in sets PF_OutFlag_I_USE_AUDIO in PF_Cmd_GLOBAL_SETUP, it will not be loaded at all
11 | - F9355 - Support PF_ParamFlag_COLLAPSE_TWIRLY
12 | - PF World Transform Suite
13 | - PF AE Channel Suite
14 | - AE's implementation of high bit color depth support
15 | - SmartFX
16 | - 3D support
17 | - PF_SUBPIXEL_SAMPLE(), PF_GET_PIXEL_DATA16()
18 |
19 | ---
20 |
21 | ## But... Why'd You LOAD It If You Can't RUN It?!
22 |
23 | Premiere Pro attempts to load AEGP plug-ins. To detect this and avoid any problem behavior, your command hook function can access a suite which is only provided by After Effects; AEGP_CanvasSuite is a fine candidate.
24 |
25 | If the suite isn't present, return an error. The plug-in will be placed on Premiere Pro's "don't load these" list.
26 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Do not modify below line! Inherits common components.
2 | INHERIT: ./docs/_global/mkdocs.yml
3 |
4 | #### Site metadata & nav - update these!
5 |
6 | site_name: After Effects C++ SDK Guide
7 | site_url: https://ae-plugins.docsforadobe.dev/
8 | repo_url: https://github.com/docsforadobe/after-effects-plugin-guide/
9 | repo_name: "after-effects-plugin-guide"
10 |
11 | nav:
12 | - Home: index.md
13 | - Version History: history.md
14 | - Introduction:
15 | - What Can I Do With This SDK?: intro/what-can-i-do.md
16 | - Other Integration Possibilities: intro/other-integration-possibilities.md
17 | - SDK Audience: intro/sdk-audience.md
18 | - What's New: intro/whats-new.md
19 | - How To Start Creating Plug-ins: intro/how-to-start-creating-plug-ins.md
20 | - Sample Projects: intro/sample-projects.md
21 | - Debugging Plug-ins: intro/debugging-plug-ins.md
22 | - Compatibility Across Multiple Versions?: intro/compatibility-across-multiple-versions.md
23 | - Third-party Plug-in Hosts?: intro/third-party-plug-in-hosts.md
24 | - PiPL Resources: intro/pipl-resources.md
25 | - Exceptions: intro/exceptions.md
26 | - Where Installers Should Put Plug-ins: intro/where-installers-should-put-plug-ins.md
27 | - Localization: intro/localization.md
28 | - Apple Silicon Support: intro/apple-silicon-support.md
29 | - Exporting Symbols in Effects: intro/symbol-export.md
30 | - Next Steps: intro/next-steps.md
31 | - Effect Basics:
32 | - Effect Basics: effect-basics/effect-basics.md
33 | - Entry Point: effect-basics/entry-point.md
34 | - Command Selectors: effect-basics/command-selectors.md
35 | - PF_InData: effect-basics/PF_InData.md
36 | - PF_OutData: effect-basics/PF_OutData.md
37 | - Parameters: effect-basics/parameters.md
38 | - PF_ParamDef: effect-basics/PF_ParamDef.md
39 | - PF_EffectWorld / PF_LayerDef: effect-basics/PF_EffectWorld.md
40 | - Errors: effect-basics/errors.md
41 | - Effect Details:
42 | - Multi-Frame Rendering in AE: effect-details/multi-frame-rendering-in-ae.md
43 | - Effect Details: effect-details/effect-details.md
44 | - Accessing the After Effects Function Suites: effect-details/accessing-function-suites.md
45 | - Memory Allocation: effect-details/memory-allocation.md
46 | - Image Buffer Management Functions: effect-details/image-buffer-management-functions.md
47 | - Iteration Suites: effect-details/iteration-suites.md
48 | - Graphics Utility Suites: effect-details/graphics-utility-suites.md
49 | - Interaction Callback Functions: effect-details/interaction-callback-functions.md
50 | - Pixel Aspect Ratio: effect-details/pixel-aspect-ratio.md
51 | - Parameters & Floating Point Values: effect-details/parameters-floating-point-values.md
52 | - Parameter Supervision: effect-details/parameter-supervision.md
53 | - Global, Sequence, & Frame Data: effect-details/global-sequence-frame-data.md
54 | - Arbitrary Data Parameters: effect-details/arbitrary-data-parameters.md
55 | - Useful Utility Functions: effect-details/useful-utility-functions.md
56 | - Motion Blur: effect-details/motion-blur.md
57 | - Working With Paths: effect-details/working-with-paths.md
58 | - Accessing Camera & Light Information: effect-details/accessing-camera-light-information.md
59 | - Color Space Conversion: effect-details/color-space-conversion.md
60 | - Changing Parameter Orders, the Nice Way: effect-details/changing-parameter-orders.md
61 | - Tips & Tricks: effect-details/tips-tricks.md
62 | - Compute Cache API: effect-details/compute-cache-api.md
63 | - SmartFX:
64 | - SmartFX: smartfx/smartfx.md
65 | - Effect UI & Events:
66 | - Effect UI & Events: effect-ui-events/effect-ui-events.md
67 | - PF_EventExtra: effect-ui-events/PF_EventExtra.md
68 | - PF_EventUnion: effect-ui-events/PF_EventUnion.md
69 | - Custom UI & Drawbot: effect-ui-events/custom-ui-and-drawbot.md
70 | - UI Callbacks: effect-ui-events/ui-callbacks.md
71 | - Tips & Tricks: effect-ui-events/tips-and-tricks.md
72 | - Audio:
73 | - Audio: audio/audio.md
74 | - Global Outflags: audio/global-outflags.md
75 | - Audio Data Structures: audio/audio-data-structures.md
76 | - Audio-Specific Float Slider Variables: audio/audio-specific-float-slider-variables.md
77 | - Accessing Audio Data: audio/accessing-audio-data.md
78 | - Audio Considerations: audio/audio-considerations.md
79 | - AEGPs:
80 | - AEGPs: aegps/aegps.md
81 | - Overview: aegps/overview.md
82 | - Data Types: aegps/data-types.md
83 | - Implementation: aegps/implementation.md
84 | - AEGP Suites: aegps/aegp-suites.md
85 | - Cheating Effect Usage of AEGP Suites: aegps/cheating-effect-usage-of-aegp-suites.md
86 | - AEGP Details: aegps/aegp-details.md
87 | - Artisans:
88 | - Artisans: artisans/artisans.md
89 | - Artisan Data Types: artisans/artisan-data-types.md
90 | - AEIOs:
91 | - AEIOs: aeios/aeios.md
92 | - Calling Sequence: aeios/calling-sequence.md
93 | - AEIO_ModuleInfo: aeios/AEIO_ModuleInfo.md
94 | - New Kids On The Function Block: aeios/new-kids-on-the-function-block.md
95 | - Implementation Details: aeios/implementation-details.md
96 | - Premiere Pro:
97 | - Premiere Pro & Other Hosts: ppro/ppro.md
98 | - Plug-in Installation: ppro/plug-in-installation.md
99 | - Basic Host Differences: ppro/basic-host-differences.md
100 | - Multithreading: ppro/multithreading.md
101 | - Bigger Differences: ppro/bigger-differences.md
102 | - Plug-Ins... Reloaded: ppro/plug-ins-reloaded.md
103 | - Premiere Elements: ppro/premiere-elements.md
104 | - Unsupported Features: ppro/unsupported-features.md
105 | - Other Hosts: ppro/other-hosts.md
106 |
107 | #### Additional config below - modify sparingly!
108 |
109 | extra:
110 | # Custom guide-specific overrides
111 | #
112 | # Valid keys are:
113 | # custom_dir: str
114 | # hooks:
115 | # - path/to/hook.py
116 | # not_in_nav:
117 | # - gitignore_style/path/to/exclude
118 | # theme_features:
119 | # - theme.feature
120 | overrides: {}
121 |
122 | # CSS for this guide
123 | extra_css:
124 | - _static/extra.css
125 |
126 | # JS for this guide
127 | extra_javascript:
128 | - _static/extra.js
129 |
130 | markdown_extensions: {}
131 |
132 | plugins: {}
133 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # After Effects C++ Plugin SDK Guide
2 |
3 | This repo hosts the After Effects C++ Plugin SDK Guide community docs.
4 |
5 | ---
6 |
7 | ## Contributing
8 |
9 | This endeavour is primarily community-supported & run; contributors are welcome and encouraged to suggest fixes, adjustments, notes/warnings, and anything else that may help the project.
10 |
11 | For specific information on how to contribute & best practices, see the [Documentation Contribution Guide](https://docsforadobe.dev/contributing/contribution-guide/).
12 |
13 | ---
14 |
15 | ## Licensing & Ownership
16 |
17 | This project exists for educational purposes only.
18 |
19 | All content is copyright Adobe Systems Incorporated.
20 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | -r docs/_global/requirements.txt
2 |
--------------------------------------------------------------------------------