RemapFrames
(add documentation (converted from html)) |
m (→RemapFrames: add link) |
||
Line 13: | Line 13: | ||
'''Download:''' | '''Download:''' | ||
*[http://ldesoras.free.fr/src/avs/RemapFrames-0.4.1.zip RemapFrames-0.4.1.zip] - for AviSynth 2.5 and greater | *[http://ldesoras.free.fr/src/avs/RemapFrames-0.4.1.zip RemapFrames-0.4.1.zip] - for AviSynth 2.5 and greater | ||
− | *[http://dl.dropboxusercontent.com/u/19797864/RemapFrames-0.4.1-avs26.zip RemapFrames-0.4.1-avs26.zip] - for AviSynth 2.6/AviSynth+ (includes 64-bit version) | + | *[http://dl.dropboxusercontent.com/u/19797864/RemapFrames-0.4.1-avs26.zip RemapFrames-0.4.1-avs26.zip] - for AviSynth 2.6/AviSynth+ (includes 64-bit version). Requires [http://www.microsoft.com/en-us/download/details.aspx?id=51682 Microsoft Visual C++ 2015 Redistributable Package (x86 / x64)] |
Revision as of 03:17, 23 May 2016
Contents |
RemapFrames
v0.4.1 (2014-01-16)
An AviSynth plug-in that remaps the frame indices in a clip as specified by an input text file or by an input string.
by James D. Lin (stickboy)
Download:
- RemapFrames-0.4.1.zip - for AviSynth 2.5 and greater
- RemapFrames-0.4.1-avs26.zip - for AviSynth 2.6/AviSynth+ (includes 64-bit version). Requires Microsoft Visual C++ 2015 Redistributable Package (x86 / x64)
Overview
RemapFrames
, RemapFramesSimple
, and ReplaceFramesSimple
provide general control over manipulation of frame indices in a clip. They can be used in cases where SelectEvery
isn't suitable, such as when the desired frames don't follow a regular pattern.
RemapFrames
/RemapFramesSimple
/ReplaceFramesSimple
also are efficient alternatives to long chains of FreezeFrame
, DeleteFrame
, or ApplyRange
calls.
RemapFramesSimple
and ReplaceFramesSimple
are less powerful than RemapFrames
but use a much simpler, more basic syntax.
remf
, remfs
and rfs
are shortcuts for RemapFrames
, RemapFramesSimple
and ReplaceFramesSimple
with slight differences. The mappings parameter comes before filename for a more compact "inline" call. These parameters are completely optional; when none of them is specified, an empty string is assumed. And when an empty string is detected, the filter is completely bypassed (no extra memory use). Also, these versions don't check aggressively the frame ranges. If a referenced frame doesn't exist, it's simply ignored or its index is replaced with the closest valid frame index. This allows working on partial ranges of a clip with a unique set of mappings.
Syntax
RemapFrames(clip baseClip, string "filename", string "mappings", clip "sourceClip") RemapFramesSimple(clip c, string "filename", string "mappings") ReplaceFramesSimple(clip baseClip, clip sourceClip, string "filename", string "mappings") remf(clip baseClip, string "mappings", string "filename", clip "sourceClip") remfs(clip c, string "mappings", string "filename") rfs(clip baseClip, clip sourceClip, string "mappings", string "filename") rfs_transform (string mappings, string "op", bool "open", bool "discrete") rfs_merge (string "s0", string "s1", …, string "s9")
RemapFrames
Parameters
baseClip
|
Frames from sourceClip are mapped into baseClip. |
"filename"
|
The name of the text file that specifies the new frame mappings. |
"mappings"
|
Mappings also may be given directly in a string. Overrides frame mappings given by filename. |
"sourceClip"
|
The source clip used to supply the new, remapped frames. |
Usage
Does not affect the audio track.
Each line in the text file or in the mappings string must have one of the following forms:
-
a z
Replaces frame a in baseClip with frame z from sourceClip. -
[a b] z
Replaces all frames in the inclusive range a..b of baseClip with frame z from sourceClip. -
[a b] [y z]
Replaces all frames in the range a..b of baseClip with frames in the range y..z from the sourceClip. If the input and output ranges do not have equal sizes, frames will be duplicated or dropped evenly from y ..z to match the size of a..b. If y > z, the order of the output frames is reversed. -
# comment
A comment. Comments may appear anywhere on a line; all text from the start of the#
character to the end of the line is ignored.
Sample data file:
[0 9] [0 4] # the first ten frames will be 0, 0, 1, 1, 2, 2, 3, 3, 4, 4 10 5 # show frame 5 in frame 10's place [15 20] 6 # replace frames 15..20 with frame 6 [25 30] [35 40] # replace frames 25..30 with frames 35..40 [50 60] [60 50] # reverse the order of frames 50..60
Within each line, all whitespace is ignored.
By default, all frames are mapped to themselves.
If multiple lines remap the same frame, the last remapping overrides any previous ones.
# the frames in the generated clip will be # 4, 0, 0, 0, 0, 0, 6, 7, ... [0 5] 0 0 3 0 4
The output clip always will have the same number of frames as the input clip. To delete frames, remap the appropriate frames and then call Trim
afterward.
BlankClip(length=100).ShowFrameNumber() # Replace frames 50..89 with 60..99. This effectively deletes frames # 50..59. RemapFrames(mappings="[50 89] [60 99]") # Trim off the excess. Trim(0, 89)
To add duplicate frames, call LengthenClip
first and then remap the appropriate frames.
BlankClip(length=100).ShowFrameNumber() LengthenClip(110) # Duplicate frame 50 ten times, and delay all the subsequent frames by # ten frames. RemapFrames(mappings="[50 59] 50 [60 109] [50 99]")
RemapFramesSimple
Parameters
"filename"
|
The name of the text file that specifies the new frame mappings. |
"mappings"
|
Mappings alternatively may be given directly in a string. Unlike RemapFrames , mappings and filename cannot be used together.
|
Usage
Does not affect the audio track.
RemapFramesSimple
takes a text file or a mappings string consisting of a sequence of frame numbers. The number of frame mappings determines the number of frames in the output clip. For example:
# Generate a clip containing only the first five frames. RemapFramesSimple(mappings="0 1 2 3 4")
# Duplicate frame 20 five times. RemapFramesSimple(mappings="20 20 20 20 20")
ReplaceFramesSimple
Parameters
baseClip sourceClip
|
Frames from baseClip are replaced by frames from sourceClip. |
"filename"
|
The name of the text file that specifies the frames to replace. |
"mappings"
|
Replacement frames alternatively may be given directly in a string. |
Usage
Does not affect the audio track.
ReplaceFramesSimple
takes a text file or a mappings string consisting of sequences or ranges of frame numbers to replace. For example:
# Replaces frames 10..20, 25, and 30 from baseClip with the # corresponding frames from sourceClip. ReplaceFramesSimple(baseClip, sourceClip, mappings="[10 20] 25 30")
# Inverse-telecine a clip and fix individual frames that still show # combing. c = src.Telecide(...).Decimate(...) deinterlaced = c.KernelDeint(...) # Replace frames 30, 40, 50 with their deinterlaced versions. ReplaceFramesSimple(c, deinterlaced, mappings="30 40 50")
rfs_transform
Parameters
"mappings"
|
A frame mapping string that can be used in ReplaceFramesSimple or rfs .
|
"op"
|
String containing the operation to perform on the original mappings. Default: "x" .
|
"open"
|
Indicates if ranges and single frames should be converted to half-open intervals before being tranformed then converted back to closed intervals. This flag is ignored when discrete is set to |
"discrete"
|
Indicates if ranges should be split into individual frames before being transformed, and possibly grouped in ranges afterwards. Default: false .
|
Usage
rfs_transform
is a helper function transforming a set of mappings for ReplaceFramesSimple
using an arithmetic operation. This is useful when one needs to substitute frames after a framerate change or any kind of timeline manipulation.
The operation is noted in Reverse Polish Notation (or Postfix). All calculation are done in double-precision floating point data. The resulting frame is rounded to the nearest (even) integer. The logical operations return 0 or 1 and assume the input is false if exactly equal to 0, true otherwise. Here is a list of the available operators:
-
neg ! round floor ceil
-
- * / mod min max == != > >= < <= && || ^^
-
clip ?
There are three input variables:
- x: the current frame index being processed,
- r: indicates if it's the frame is the beginning of a range (0) or the end (1),
- y: the other range boudary.
Excepted in discrete mode, single frames are considered as a ranges containing one frame. In half-open interval mode, the end of the range is augmented of 1 before the calculation. This ensures that the ranges and their implicit complementary intervals are treated equaly, with more consistency. This is an easy solution to avoid gaps at the range boundaries when the timeline is dilated.
When a range is reverted (time inversion), the function automatically swaps the resulting range boundaries and keep everything consistent.
Frames indexes are truncated if they go below 0, but there is no upper bound check. In half-open mode, the end of the clip is indexed by the frame after the last frame (whose number equals the total number of frames), whereas in closed mode, the end is the last frame (total number of frames minus 1).
Examples:
# Shifts the mappings 10 frames forward rfs_transform ("[100 199] 300 [400 999]", op="x 10 ") # result: "[110 209] 310 [410 1009]"
# Dilates the mappings 5 times rfs_transform ("[100 199] 300 [400 999]", op="x 5 *") # result: "[500 999] [1500 1504] [2000 4999]"
rfs_merge
Parameters
"s0" , …, "s9"
|
Strings that can be used in ReplaceFramesSimple or rfs . Default: undefined.
|
Usage
rfs_merge
is a helper function merging several mappings for ReplaceFramesSimple
together. It just concatenates these strings and inserts spaces in between, but it is probably more convenient than a simple concatenation because it handles properly the undefined strings. If all strings are undefined, the result is also an undefined string.
Example:
# Shifts the mappings 10 frames forward rfs_transform ("[100 199]", "300", "[400 999]") # result: "[100 199] 300 [400 999]"
Adapting Existing Scripts
Using FreezeFrame
|
Using RemapFrames
|
---|---|
BlankClip(length=100).ShowFrameNumber() FreezeFrame(10, 11, 10) FreezeFrame(15, 16, 16) FreezeFrame(20, 24, 21) FreezeFrame(30, 32, 31) FreezeFrame(35, 36, 36) |
BlankClip(length=100).ShowFrameNumber() RemapFrames(mappings="[10 11] 10 [15 16] 16 [20 24] 21 [30 32] 31 [35 36] 36") |
Using ApplyRange
|
Using ReplaceFramesSimple
|
---|---|
BlankClip(length=100).ShowFrameNumber() ApplyRange(10, 11, "SomeFilter") ApplyRange(15, 16, "SomeFilter") ApplyRange(20, 24, "SomeFilter") ApplyRange(30, 32, "SomeFilter") ApplyRange(35, 36, "SomeFilter") |
src = BlankClip(length=100).ShowFrameNumber() filtered = src.SomeFilter() ReplaceFramesSimple(src, filtered, \ mappings="[10 11] [15 16] [20 24] [30 32] [35 36]") |
Revision History
- 0.4.1
- It is now allowed for a downstream filter to request a frame out of range.
-
rfs_transform
now accepts an undefined mapping string as input.
- 0.4.0
- Added
remf
,remfs
,rfs
,rfs_merge
andrfs_transform
.
- Added
- 0.3.1
- Fixed
RemapFrames
which was seriously broken because I forgot that initial clip parameters can't be optional. As a consequence, I had to rearrangeRemapFrames
's parameter order.
- Fixed
- 0.3.0
- Added
ReplaceFramesSimple
.
- Added
- 0.2.0
- Added
RemapFramesSimple
.
- Added
- 0.1.1
- Now retains field parity information of the remapped frames.
- 0.1.0
- Initial release.