(本文未经许可禁止转载)

           

分数式定义

Ae SDK CC 2017中,时间被定义为如下这种形式:

typedef struct {
    A_long value;
    A_u_long scale;
} A_Time;

一般的软件中,我们会倾向于把时间定义为double(秒)的形式,但对于非常大的时间数据来说,double难免会存在浮点误差,Ae的这种定义是采用分数定义的。我们获取秒的方法很简单:

A_Time aetime;
/* 从AEGP套件获取Ae时间数据*/
double sec_time = ( (double)aetime.value )/((double) aetime.scale )

最后这里的sec_time就是A_Time的直观秒数据。

Ae这里的设计方式会把时间误差产生的位置从Ae主体转移(甩锅)到插件上。不过从另一个角度上也看出Ae在时间设计这上面的良苦用心233。

从PF插件框架获取合成时间

一般在渲染函数(Smart render)里,我们通过in_data获取的time_valuetime_scale只是插件所在图层的图层时间,而图层时间不会随用户平移图层而发生改变。

有些时候我们希望插件能获取到图层所在的合成的总时间,这时候就需要用到AEGP插件框架下的函数帮我们逐一获取我们想要的数据。

以下是PixelsWorld工程中使用的获取合成时间的源码

do
{
    A_Time comptime;

    ERR(suites.PFInterfaceSuite1()->AEGP_ConvertEffectToCompTime(
    in_data->effect_ref,
    in_data->time_step,
    in_data->time_scale,
    &comptime));

 }while(0);

最后我们再把comptime拿去做我们想要的处理即可。

举例

最后,我们观察一下以下图层的A_Time信息

图层摆放样式

Debug 结果

in_data->current_time 12000
in_data->time_scale 23976
comptime.value 24000
comptime.scale 23976

结论

  • time_scale的值没有和fps的直观转换方式。比如我们上面的图的帧率是29.97,但scale值并没有出现诸如29970之类的形式。
  • 但是time_scale的存在能保证目前时间数据是足够精准的。

获取fps数据

那么我们怎么获取fps数据呢?这里就需要我们进行以下操作逐一获取fps

下面的代码也是在PixelsWorld中服役的源码

AEGP_LayerH layerH;
ERR(suites.PFInterfaceSuite1()->AEGP_GetEffectLayer(in_data->effect_ref, &layerH));
AEGP_CompH compH;
ERR(suites.LayerSuite8()->AEGP_GetLayerParentComp(layerH,&compH));
A_FpLong fps;
ERR(suites.CompSuite11()->AEGP_GetCompFramerate(compH, &fps));

Time scale的计算方法

虽然前面说scale好像没有统一的公式能计算它。但是我们仍能猜测出Ae是怎么算出它的。它的基本公式如下:

Scale=Step \times Fps

其中这里的Fps不是浮点数,是十进制小数。新出现的Step目前只能看出来是Ae随性定义的(它在in_data->time_step)。Ae保证这两个数相乘出来的Scale一定是个足够大的整数。

一些测试数据

我测了两个fps下的scale和step

  • fps:29.97, step:800,scale:23976
  • fps:60, step:512,scale:30720

他们均满足上面的等式。

两帧之间的关键帧

我们时常会看到有一些奇葩的工程,关键帧出现在两帧之间,其实这就是因为两帧之间还存在step个细分单位允许继续分配关键帧。比如fps为60的时候,step为512。那么这时两个帧之间理论上就有511个等均的位置可以分配关键帧。

       

(本文未经许可禁止转载)

   

发表回复