VapourSynth 1.0 documentation
previous | next | index

# FrameEval

`std.``FrameEval`(clip clip, func eval[, clip[] prop_src])

  Allows an arbitrary function to be evaluated every frame. The function gets the frame number, n, as input and should return a clip the output frame can be requested from.

  The clip argument is only used to get the output format from since there is no reliable automatic way to deduce it.

  When using the argument prop_src the function will also have an argument, f, containing the current frames. This is mainly so frame properties can be accessed and used to make decisions. Note that f will only be a list if more than one prop_src clip is provided.

  This function can be used to accomplish the same things as Animate, ScriptClip and all the other conditional filters in Avisynth. Note that to modify per frame properties you should use ModifyFrame.

  How to animate a BlankClip to fade from white to black. This is the simplest usage case without using the prop_src argument:

      import vapoursynth as vs
      import functools

      core = vs.get_core()
      base_clip = core.std.BlankClip(format=vs.YUV420P8, length=1000, color=[255, 128, 128])

      def animator(n, clip):
         if n > 255:
            return clip
         else:
            return core.std.BlankClip(format=vs.YUV420P8, length=1000, color=[n, 128, 128])

      animated_clip = core.std.FrameEval(base_clip, functools.partial(animator, clip=base_clip))
      animated_clip.set_output()

  How to perform a simple per frame auto white balance. It shows how to access calculated frame properties and use them for conditional filtering:

      import vapoursynth as vs
      import functools
      import math

      def GrayWorld1Adjust(n, f, clip, core):
         red   = f[0].props.PlaneAverage
         green = f[1].props.PlaneAverage
         blue  = f[2].props.PlaneAverage
         max_rgb = max(red, green, blue)
         red_corr   = max_rgb/red
         green_corr = max_rgb/green
         blue_corr  = max_rgb/blue
         norm = math.sqrt(red_corr*red_corr + green_corr*green_corr + blue_corr*blue_corr) / math.sqrt(3)
         r_gain = red_corr/norm
         g_gain = green_corr/norm
         b_gain = blue_corr/norm
         return core.std.Expr(clip, expr=['x ' + repr(r_gain) + ' *', 'x ' + repr(g_gain) + ' *', 'x ' + repr(b_gain) + ' *'])

      def GrayWorld1(clip):
         core = vs.get_core()
         rgb_clip = core.resize.Bilinear(clip, format=vs.RGB24)
         r_avg = core.std.PlaneAverage(rgb_clip, plane=0)
         g_avg = core.std.PlaneAverage(rgb_clip, plane=1)
         b_avg = core.std.PlaneAverage(rgb_clip, plane=2)
         adjusted_clip = core.std.FrameEval(rgb_clip, functools.partial(GrayWorld1Adjust, clip=rgb_clip, core=core), propsrc=[r_avg, g_avg, b_avg])
         return core.resize.Bilinear(adjusted_clip, format=clip.format.id)

      core = vs.get_core()
      core.std.LoadPlugin(path='ffms2.dll')
      main = core.ffms2.Source(source='...')
      main = GrayWorld1(main)
      main.set_output()