ApplyEvery

From Avisynth wiki
Revision as of 19:30, 26 May 2020 by Reel.Deal (Talk | contribs)

Jump to: navigation, search
Abstract
Author James D. Lin (stickboy)
Version v0.3.1
Download ApplyEvery.zip
Category Frame Replacement / Range Processing
License GPLv2
Discussion Doom9 Thread

Contents

Description

A collection of AviSynth functions that operate at regular intervals in a clip.

Requirements


Overview

ApplyEvery is a general function to apply a filter at regular intervals in a clip.

DeleteEvery deletes frames from a clip at regular intervals. It complements to the built-in SelectEvery function.

DeleteFrames is a supplement to the built-in DeleteFrame function. DeleteFrames provides a reasonably efficient means to delete multiple frames from a clip.

InterleaveEvery allows two clips to be mixed together in a specified pattern. It can undo the work of SelectEvery and DeleteEvery.

RepeatEveryFrame repeats every frame in a clip a specified number of times.

LengthenClip pads frames to the end of a clip to give it a minimum number of frames.

WhileEval provides a crude looping construct.


Syntax

ApplyEvery(clip c, int period, string thunk)

DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]])
DeleteFrames(clip c, int frame1 [, int frame2 [, ...]])

InterleaveEvery(clip baseClip, clip shimClip,
                int period [, int offset1 [, int offset2 [, ...]]])

RepeatEveryFrame(clip c, int count)

LengthenClip(clip c, int minLength, bool "copy", int "color")

WhileEval(string condition, string loopBody)

ApplyEvery

Syntax

ApplyEvery(clip c, int period, string thunk)

Parameters

period The interval length, in frames. Must be > 0.
thunk The action to perform on the frames in the interval.


Usage

A general function to apply a filter at regular intervals in a clip. This function is not very efficient, so it's recommended that this function be used only if a combination of SelectEvery, DeleteEvery, and InterleaveEvery cannot suit your needs.

If the total number of frames is not a multiple of period, then silent, blank frames will be appended to the end of the output clip. It is the caller's responsibility to remove these afterward as necessary. (One of the examples below demonstrates how to remove these extra frames.)

Examples:

# deletes the 0th frame of every 100
#
# (NOTE: if you want to do this, DeleteEvery is better)
#
ApplyEvery(clip, 100, "DeleteFrame(0)")
# inverts the first two frames of every 5
#
# (NOTE: if you want to do this, a combination of SelectEvery, DeleteEvery,
#        and InterleaveEvery is better)
#
ApplyEvery(clip, 5, """ApplyRange(0, 1, "Levels", 0, 1.0, 255, 255, 0)""")
# reverses every group of 4 frames
ApplyEvery(clip, 4, "Reverse()")
# how to correct the frame-length
# (assumes that thunk does not itself modify the frame-count)
#
n = clip.FrameCount()
ApplyEvery(clip, period, thunk)
Trim(0, -n)

DeleteEvery

Syntax

DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]])

Parameters

period The interval length, in frames. Must be > 0.
offset1 [, ...] The offsets of each frame to delete, measured from the beginning of the interval. (See Usage for examples.) Each offset must be in the range [0, period). Order of the offsets does not matter.


Usage

DeleteEvery reduces the frame-rate proportionately. For example, DeleteEvery(clip, 3, 0, 1) will reduce the frame-rate to one-third of its original value. DeleteEvery does not affect the audio track.

DeleteEvery(clip, 9, 0) will delete frames 0, 9, 18, 27, … from clip.

DeleteEvery(clip, 9) is equivalent to DeleteEvery(clip, 9, 0).

DeleteEvery(clip, 10, 0, 3) will delete frames 0, 3, 10, 13, 20, 23, … from clip.

DeleteEvery complements the built-in SelectEvery function; SelectEvery(4, 0, 1, 2) is equivalent to DeleteEvery(4, 3).

DeleteEvery(clip, period, 0) is conceptually equivalent to ApplyEvery(clip, period, "DeleteFrame(0)"). In practice, DeleteEvery is much more efficient than ApplyEvery. (Another difference is that DeleteEvery adjusts the frame-rate.)


DeleteFrames

Syntax

DeleteFrames(clip c, int frame1, [, int frame2 [, ...]])

Parameters

frame1 [, ...] The frames to delete.


Usage

Like the built-in DeleteFrame function, DeleteFrames does not affect the audio track nor the frame-rate. Therefore, if enough frames are deleted, it may cause significant audio/video desynchronization.

Advantages of DeleteFrames over the built-in DeleteFrame function:

  • Repeatedly calling the built-in DeleteFrame function is tedious.
  • Repeatedly calling the built-in DeleteFrame function is inefficient; each call generates a new clip, wasting resources.
  • Repeated calls to the built-in DeleteFrame function must be performed in reverse order to prevent each call from affecting the frame numbers in subsequent calls. In contrast, the frame numbers passed to DeleteFrames may be in any order.

DeleteFrames(clip, ...) essentially is shorthand for DeleteEvery(clip, clip.FrameCount(), ...). (They are not exactly the same, however; DeleteFrames does not affect the frame-rate.)


InterleaveEvery

Syntax

InterleaveEvery(clip baseClip, clip shimClip,
                int period [, int offset1 [, int offset2 [, ...]]])

Parameters

baseClip

shimClip

Frames from shimClip are inserted into baseClip. Both clips must have the same width, height, and colorspace properties.
period The output interval length, in frames. Must be > 0.
offset1 [, ...] The destination offsets to place frames from shimClip. (See Usage.) Each offset must be in the range [0, period).


Usage

InterleaveEvery inserts frames at regular intervals from shimClip into baseClip at the specified offsets. For example:

clip frames
baseClip 0 1 2 3 …
shimClip a b c d
InterleaveEvery(baseClip, shimClip, 5, 0) a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d
InterleaveEvery(baseClip, shimClip, 5, 0, 1) a b 0 1 2 c d 3 4 5 e f 6 7 8 g h

InterleaveEvery continues until there are no more frames in baseClip:

clip frames
baseClip 0 1 2 3 4 5 6
shimClip a b c d
InterleaveEvery(baseClip, shimClip, 5, 0) a 0 1 2 3 b 4 5 6

If shimClip does not have enough frames to insert into baseClip, the last frame of shimClip will be repeated:

clip frames
baseClip 0 1 2 3 …
shimClip a b
InterleaveEvery(baseClip, shimClip, 5, 0) a 0 1 2 3 b 4 5 6 7 b 8 9 10 11 b

Offset order determines where particular frames from shimClip are inserted:

clip frames
baseClip 0 1 2 3 …
shimClip a b c d
InterleaveEvery(baseClip, shimClip, 5, 1, 0) b a 0 1 2 d c 3 4 5 f e 6 7 8 h g

InterleaveEvery increases the frame-rate proportionately to preserve the total duration of baseClip. For example, InterleaveEvery(baseClip, shimClip, 5, 0, 1) will return a clip with a frame-rate that is five-thirds of baseClip's.

The output clip uses the unaltered audio track of baseClip.

Note that the period and offset parameters specify the desired periodicity of the output clip, not of the base clip. This syntax is designed to ease interoperability with SelectEvery and DeleteEvery. The same arguments used to extract frames with SelectEvery/DeleteEvery can be used to put them back with InterleaveEvery.

For example, to invert the first two frames of every group of five, we could use:

src = AVISource( ... )

# pull out the frames we want
subClip = src.SelectEvery(5, 0, 1)
src = src.DeleteEvery(5, 0, 1)

# invert subClip
subClip = subClip.Levels(0, 1.0, 255, 255, 0)

# inject the frames back in
src.InterleaveEvery(subClip, 5, 0, 1)

My JDL_SimpleApplyEvery function (part of jdl-range.avsi) automates the above.


RepeatEveryFrame

Syntax

RepeatEveryFrame(clip c, int count)

Parameters

count The number of times to repeat each frame.


LengthenClip

Syntax

LengthenClip(clip c, int minLength, bool "copy", int "color")

Parameters

minLength The minimum length desired for the clip.
"copy" Pass true to lengthen the clip by duplicating its last frame.

Pass false to lengthen the clip by appending blank frames to the end.
(Default: false)

"color" The RGB color to use for appended, blank frames.

(Default: $000000 (black))


Usage

If the input clip already meets the minimum length, LengthenClip has no effect.

(This function doesn't belong with the rest, but it's provided because it's used by ApplyEvery.)


WhileEval

Syntax

WhileEval(string condition, string loopBody)

Parameters

condition A string representing the looping condition. The loop continues as long as the string evaluates to true.
loopBody The body of the loop. May consist of multiple lines. (See Usage.)


Usage

WhileEval provides a very crude, static looping construct. That is, the loop is processed when the script is initially loaded.

WhileEval is not very efficient. A large number of iterations may cause a script to be slow to load; too many iterations may prevent AviSynth from loading the script at all. Although WhileEval should consume fewer resources than recursive looping constructs (AviSynth currently does not optimize tail-recursive calls), ApplyEvery, SelectEvery/DeleteEvery/InterleaveEvery, Animate, or ScriptClip/FrameEvaluate should be considered first when possible.

The example below is yet another way to delete the 0th frame of every 100. (Again, for this specific task, using DeleteEvery would be better.)

c = AVISource( ... )

i = c.FrameCount() - 1

# this is NOT a no-op; this rounds i down to the next highest multiple
# of 100
i = i / 100 * 100
WhileEval("i >= 0",
\         "c = c.DeleteFrame(i)
           i = i - 100")
c

Revision History

  • 0.3.1
    • Fixed(?) some off-by-one errors in InterleaveEvery.
  • 0.3.0
    • Added RepeatEveryFrame.
    • Fixed some integer overflow cases.
  • 0.2.3
    • Oops, 0.2.2 accidentally undid the changes from 0.2.1. Fixed.
  • 0.2.2
    • Added WhileEval.
  • 0.2.1
    • Minor adjustments to handling of 0-frame clip inputs.
  • 0.2.0
    • Merged with my DeleteEvery/DeleteFrames plug-in.
    • Added InterleaveEvery.
    • Added documentation for LengthenClip.
  • 0.1.0
    • Initial release.





Back to External Filters


Personal tools