AEJoy —— AE 插件开发中的 全局、序列、帧数据

全局、序列、帧数据

After Effects 允许插件在三个范围存储数据: 全局序列。 仔细考虑将信息存储在何处; 选择不当会影响性能,或者让用户感到困惑。

全局数据用于所有效果实例的公共信息: 静态变量和数据、位图、指向其他 DLL 或外部应用程序的指针。 如果你的效果支持多帧渲染,任何静态或全局变量都必须不存在竞争条件(参见效果线程安全意味着什么? 的更多信息)。

将任何特定于此插件实例的内容( UI 设置、文本字符串和任何未存储在参数中的自定义数据)存储在序列数据或新的多帧渲染计算缓存中。

帧数据用于特定于渲染给定帧的信息。 这已经被废弃了,因为大多数机器一次可以将整个帧加载到内存中。 当然,生成 IMAX 的用户仍然会欣赏您所做的任何优化。

持续性

After Effects 在项目文件中保存序列数据,但不保存全局数据。序列数据中指向外部数据的指针在重新打开项目时很可能无效,必须重新连接。我们称这个过程为序列数据的“平展化”和“非平展化”。

注意:计算缓存不会将其内容存储到项目文件中。必须在渲染期间重新创建存储在缓存中的数据。

验证序列数据

仔细的序列数据验证对于跨时间进行模拟的效果非常重要,因为第 N 帧依赖于第 N-1 帧,并且您在序列数据中使用了计算数据的缓存。 如果一个参数改变了,某些计算的数据可能不再有效,但盲目地在每次更改后重新计算一切也是浪费

当要求渲染第 N 帧时,假设您已经计算了缓存数据到第 N-1 帧,从 PF_ParamUtilSuite3 调用 PF_GetCurrentState() / PF_AreStatesIdentical() 来查看计算数据的缓存在当前参数设置下是否仍然有效。

所有参数的状态(除了那些设置了 PF_ParamFlag_EXCLUDE_FROM_HAVE_INPUTS_CHANGED 的参数),包括层参数(包括 param[0] )在过去的时间跨度内进行检查。

它能有效地完成,因为更改跟踪是用时间戳完成的。

如果输入没有改变,您可以安全地使用缓存,并且内部缓存系统将假定您对传递的范围(passed range)有时间依赖性。 因此,如果上游(upstream)发生变化,主机的缓存将自动失效。

为了测试它的工作,在每一帧,在一个打上关键帧的参数上应用你的效果。 RAM 预览填充缓存,然后改变其中一个关键帧。 相关联的帧和所有依赖的帧(例如,在模拟的情况下,后面的帧)应该失去它们的缓存标记并需要重新渲染。 类似地,对层参数来源的上游的变化应该会导致缓存的时间选择性(time-selective)失效。

展平化和非展平化的序列数据

如果序列数据引用外部内存(在指针或句柄中),则必须将数据平展化非平展化以实现磁盘安全存储。这类似于创建自己的微型文件格式。

在接收到 PF_Cmd_SEQUENCE_FLATTEN 后,将指针引用的数据放到一个连续块中,稍后可以从这个块中恢复旧的结构。

如果序列数据包含一个指向 long 的指针,分配 4 个字节来存储平展化的数据。您必须处理平台特定的字节排序。

请记住,您的用户(购买了两个插件副本的用户)可能希望在 macOS 和 Windows 上使用相同的项目。

当数据重新加载后,无论是平展化的数据还是非平展化的数据,Effects 都会发送 PF_Cmd_SEQUENCE_RESETUP

在两个结构的共同偏移量处使用标志来指示数据的状态。

typedef struct {
  A_char*    messageZ;
  PF_FpLong  big_numF;
  void*      temp_storage;
} non_flat_data;

typedef struct {
  char       message[256];
  PF_FpLong  big_numF;
  A_Boolean  big_endianB;
} flat_data;
复制代码

缩放序列数据

PF_Cmd_SEQUENCE_SETUP 期间,为特定于你的效果实例的数据分配句柄。

您可以在任何选择器中修改序列数据的内容,但不能修改序列数据的大小

你只能在以下选择器中调整序列数据句柄的大小:

  • PF_Cmd_AUDIO_SETUP
  • PF_Cmd_AUDIO_SETDOWN
  • PF_Cmd_FRAME_SETUP
  • PF_Cmd_FRAME_SETDOWN
  • PF_Cmd_AUDIO_RENDER
  • PF_Cmd_RENDER
  • PF_Cmd_SEQUENCE_SETUP
  • PF_Cmd_SEQUENCE_SETDOWN
  • PF_Cmd_SEQUENCE_FLATTEN
  • PF_Cmd_SEQUENCE_RESETUP
  • PF_Cmd_DO_DIALOG

在多帧渲染的渲染时刻访问 sequence_data

当对一个效果启用多帧渲染时, sequence_data 对象在渲染期间将是只读的 const ,并且可以通过 PF_EffectSequenceDataSuite1 套件在每个渲染线程上访问。

PF_EffectSequenceDataSuite1

PF_GetConstSequenceData

当启用多帧渲染效果时,检索渲染线程的只读 const sequence_data 对象。

PF_Err(*PF_GetConstSequenceData)(
  PF_ProgPtr effect_ref,
  PF_ConstHandle *sequence_data);
复制代码
static PF_Err Render(
   PF_InData   *in_dataP,
   PF_OutData  *out_dataP,
   PF_ParamDef *params[],
   PF_LayerDef *output )
{
    PF_ConstHandle seq_handle;

    AEFX_SuiteScoper<PF_EffectSequenceDataSuite1> seqdata_suite = ///< 获取套件
      AEFX_SuiteScoper<PF_EffectSequenceDataSuite1>(
        in_dataP,
        kPFEffectSequenceDataSuite,
        kPFEffectSequenceDataSuiteVersion1,
        out_dataP);

    PF_ConstHandle const_seq; ///< 只读对象
    seqdata_suite->PF_GetConstSequenceData(in_data->effect_ref, &const_seq);
 ​
    // 将 const_seq 转换为存储到 sequence_data 时使用的类型

    // rest of render function code...
}
复制代码

猜你喜欢

转载自juejin.im/post/7033569184109985823
AE