AviSynth Syntax - Frame properties¶
The concept was ported from VapourSynth.
Frame properties are per-frame data. Source or other filters can store useful data into frame properties such as information on colorimetry.
Imagine them as an array of zero or more elements of PropertyName=Value pairs.
Reading or writing them is possible either in runtime environment or at the normal script level.
Avisynth provides the necessary framework for handling (set, read, clear, pass) such properties, both from users scripts and from the Filter SDK.
Before v3.6.2test7 none of its internal functions (such as color space converters) were able to set or work upon frame property values. However the set of frame properties which are actively used by Avisynth core can extend in later versions. E.g. in 3.7.x color space converters or even "Text" filter read and/or set some colormetry or color matrix related properties.
And there are external filters (like avsresize) and source plugins that use frame properties.
Developer info (see also in Filter SDK):
On filter level the set of frame properties should be copied from a previous (or specific) input frame.
When a filter is using env->MakeWritable
in its GetFrame
method this happens automatically.
A simple env->NewVideoFrame
however means a dead-end for frame property passing mechanism. Filter
must either use env->NewVideoFrameP
which has an additional parameter: a source frame (origin) of
the frame properties. Or frame properties have to be copied later, programatically by the copyFrameProps
ScriptEnvironment
function.
For compatibility reasons NewVideoFrameP
must be called adaptively instead of the traditional
NewVideoFrame
, since it does not exist in older Avisynth versions. Only usable after detecting
Avisynth interface version 8 (NewVideoFrameP was introduced in v8).
What happens if this copy is not done properly? Nothing deadly, but then the filter is a dead-end for the flow of frame properties since NewVideoFrame constructs new frame without them. Old filters which are not written with this in mind will behave like this.
Frame property getter functions are evaluated at every frame. They can be used inside the scripts passed to runtime filters (ScriptClip).
Frame property setters can be called both at script level and in runtime. When a property is set on script level it will be constant along the lifetime of the whole clip, unless it is changed in runtime, inside ScriptClip.
Definition¶
Frame properties are stored as key-value pairs. Each video frame can contain such a list, which can even be different from frame to frame.
Key is an alphanumeric identifier.
Value can be of single value or array of type
64 bit integer (32 bit integer when converted to AVSValue inside Avisynth+, AVSValue limitation)
64 bit double (32 bit float when converted to AVSValue inside Avisynth+, AVSValue limitation)
string (or byte data) with given length. Strings are null terminated. The content whether it is string or binary data can be given as a hint; from Avisynth scripting only strings allowed.
frame reference (PVideoFrame)
clip reference (PClip)
Manipulation modes¶
Property setting has 3 modes: 0-replace 1-append 2-touch.
(for developers: see AVSPropAppendMode
in avisynth.h)
0 - single value for that key is replaced
1 - property is appended (make arrays by calling with mode=1 consecutively)
2 - touch (deprecated, just creates the key)
Reserved frame property names¶
There are quasi-standard frame property names which are used widespread.
Some of them are used in Avisynth core:
_ChromaLocation
_ColorRange
_Matrix
but the others are used only by external plugins.
Frame property concept came from VapourSynth (see "Reserved Frame Properties" at http://www.vapoursynth.com/doc/apireference.html). But it is convenient that Avisynth plugins use the same property names and their and values.
Keys starting with _ have strictly defined meanings specified below. It is acceptable to not set any of these keys if they are unknown. It is also a fatal error to set them to a value not specified below.
_ChromaLocation¶
int _ChromaLocation
Chroma sample position in YUV formats.
0=left, 1=center, 2=topleft, 3=top, 4=bottomleft, 5=bottom.
Synonyms:
left, mpeg2
center, jpeg, mpeg1
_ColorRange¶
int _ColorRange
Full or limited range (PC/TV range). Primarily used with YUV formats, but can mark Studio RGB as well.
0=full range, 1=limited range (RGB: narrow range).
_Primaries¶
int _Primaries
Color primaries as specified in ITU-T H.265 Table E.3.
_Matrix¶
int _Matrix
Matrix coefficients as specified in ITU-T H.265 Table E.5.
_Transfer¶
int _Transfer
Transfer characteristics as specified in ITU-T H.265 Table E.4.
_FieldBased¶
int _FieldBased
If the frame is composed of two independent fields (interlaced).
0=frame based (progressive), 1=bottom field first, 2=top field first
_AbsoluteTime¶
float _AbsoluteTime
The frame’s absolute timestamp in seconds if reported by the source filter. Should only be set by the source filter and not be modified. Use durations for all operations that depend on frame length.
_DurationNum¶
int _DurationNum
_DurationDen¶
int _DurationDen
The frame’s duration in seconds as a rational number. Filters that modify the framerate should also change these values.
This fraction (_DurationNum/_DurationDen) should always be normalized.
_Combed¶
int _Combed (boolean)
Whether or not the frame needs postprocessing, usually hinted from field matching filters.
_Field¶
int _Field
This property signals which field was used to generate this frame. VapourSynth is using it in core.std.SeparateFields, in Avisynth core it is not used at all.
0=from bottom field, 1=from top field.
_PictType¶
string _PictType
A single character describing the frame type. It uses the common IPB letters but other letters may also be used for formats with additional frame types.
_SARNum¶
int _SARNum
_SARDen¶
int _SARDen
Pixel (sample) aspect ratio as a rational number.
_SceneChangeNext¶
int _SceneChangeNext (boolean)
If 1, this frame is the last frame of the current scene. The next frame starts a new scene.
_SceneChangePrev¶
int _SceneChangePrev (boolean)
If 1, this frame starts a new scene.
Property set¶
Input value of setter functions are to be come either
from the return value of "function objects"
direct value
Property setter function names begin with propSet
Common parameters:
clip c,
string key_name,
direct value of supported types (integer, float, string, array, clip) or a "function object"
int "mode": 0=replace (default), 1=append, 2=touch. There is no append mode for inserting a full array into the property.
propSet¶
propSet(clip, string key_name, function func_obj [, integer "mode"])
generic property setter, automatic type recognition by the return value of the function object
propSet(clip, string key_name, integer value [, integer "mode"])
propSet(clip, string key_name, float value [, integer "mode"])
propSet(clip, string key_name, string value [, integer "mode"])
propSet(clip, string key_name, array value)
propSet(clip, string key_name, clip value [, integer "mode"])
The above functions are setting a property from a directly passed values
note: array must contain only the similarly typed values, e.g. cannot mix strings with integers.
propSetInt¶
propSetInt(clip, string key_name, function func_obj [, integer "mode"])
propSetFloat¶
propSetFloat(clip, string key_name, function func_obj [, integer "mode"])
propSetString¶
propSetString(clip, string key_name, function func_obj [, integer "mode"])
propSetArray¶
propSetArray(clip, string key_name, function func_obj [, integer "mode"])
propSetClip¶
propSetClip(clip, string key_name, function func_obj [, integer "mode"])
these setters accept only the specific type
Property get¶
Get properties by name or as a whole.
Since AviSynth 3.7.1: allow propGetXXX property getter functions called as normal functions, outside runtime.
By default frame property values are read from frame#0 which index can be overridden by the offset parameter.
When called from inside runtime functions will return frame properties of the actual frame (+offset).
Common parameters:
clip c,
string key_name,
integer "index", (default 0): for zero based indexing array access
integer "offset" (default 0), similar to the other runtime functions: frame offset (e.g. -1: previous, 2: next next)
propGetAny¶
propGetAny(clip, string key_name[, integer "index", integer "offset"])
returns the automatically detected type
propGetInt¶
propGetInt(clip, string key_name[, integer "index", integer "offset"])
returns only if value is integer, throws an error otherwise (note: unlike Avisynth integer frame properties internally use 64 bit integers)
propGetFloat¶
propGetFloat(clip, string key_name[, integer "index", integer "offset"])
If the content is not of floating point type, it throws an error. Until version 3.7.3, the internal representation of floating point numbers was 32-bit float. Starting from Avisynth 3.7.4, float frame properties are read as real 64-bit doubles.
propGetString¶
propGetString(clip, string key_name[, integer "index", integer "offset"])
returns only if value is string, throws an error otherwise
propGetAsArray¶
propGetAsArray(clip, string key_name[, integer "index", integer "offset"])
A frame property can hold multiple values of the same type: it can be an array.
propGetAsArray
returns an array. For a single property the array size will be 1.
propGetClip¶
propGetClip(clip, string key_name[, integer "index", integer "offset"])
returns only if value is clip, throws an error otherwise
propGetAll¶
propGetAll(clip [, integer "offset"])
Returns all frame properties in an array of [key-value] pairs. Array size will be numProps
Each key-value pair is contained in a two dimensional subarray. If the property value itself is an array again then "value" will be an array as well.
This array contains all properties of the specific frame.
They are accessible with the associative feature of AviSynth array access. (See syntax there)
Example:
ScriptClip("""last.propSet("cica","hello"+String(current_frame)).\
propSetInt("test_i1",function[](clip c) { return current_frame*3 }).\
propSet("test_i2", current_frame * 2) """)
ScriptClip("""p = propGetAll() \
SubTitle("size:" + String(p.ArraySize()) + " " + \
String(p["test_i1"]) + " " + \
String(p["cica"]) + " " + \
String(p["test_i2"]))""")
ScriptClip("""p = propGetAll() \
SubTitle("size:" + String(p.ArraySize()) + " " + \
String(p[0,1]) + " " + \
String(p[1,1]) + " " + \
String(p[2,1]), x=0, y=20)""")
Example (read-write basic)
ColorBars()
# just practicing with function objects
ScriptClip(function[](clip c) { c.Subtitle(String(current_frame)) })
# write frame properties with function object
ScriptClip("""propSetInt("frameprop_from_str",func(YPlaneMax))""")
# write frame properties with traditional script string
ScriptClip(function[](clip c) { propSetInt("frameluma_sc_func",func(AverageLuma)) })
# read frame properties (function object, string)
ScriptClip(function[](clip c) { SubTitle(string(propGetInt("frameprop_from_str")), y=20) })
ScriptClip("""SubTitle(string(propGetInt("frameluma_sc_func")), y=40)""")
return last
Example (almost everything)
ColorBars(width=640, height=480, pixel_type="yv12", staticframes=true)
ScriptClip(function[](clip c) { propSetString("s",function[](clip c) { return "Hello " + string(current_frame) }) })
ScriptClip(function[](clip c) { propSetString("s",function[](clip c) { return "Hello array element #2 " }, mode=1) })
ScriptClip(function[](clip c) { propSetString("s",function[](clip c) { return "Hello array element #3 "}, mode=1 ) })
ScriptClip(function[](clip c) { propSetString("s2",function[](clip c) { return "Another property "} ) })
ScriptClip(function[](clip c) { propSetInt("s_int",function[](clip c) { return current_frame*1 }) })
ScriptClip(function[](clip c) { propSetInt("s_int",function[](clip c) { return current_frame*2 }, mode=1) })
ScriptClip(function[](clip c) { propSetInt("s_int",function[](clip c) { return current_frame*4 }, mode=1 ) })
ScriptClip(function[](clip c) { propSetFloat("s_float",function[](clip c) { return current_frame*1*3.14 }) })
ScriptClip(function[](clip c) { propSetFloat("s_float",function[](clip c) { return current_frame*2*3.14 }, mode=1) })
ScriptClip(function[](clip c) { propSetFloat("s_float",function[](clip c) { return current_frame*3*3.14 }, mode=1 ) })
ScriptClip(function[](clip c) { propSetArray("s_float_arr",function[](clip c) { return [1.1, 2.2] } ) })
ScriptClip(function[](clip c) { propSetArray("s_int_arr",function[](clip c) { return [-1,-2,-5] } ) })
ScriptClip(function[](clip c) { propSetArray("s_string",function[](clip c) { return ["ArrayElementS_1", "ArrayElementS_2"] } ) })
#ScriptClip("""propDelete("s")""")
ScriptClip(function[](clip c) {
y = 0
SubTitle("Prop Key count =" + String(propNumKeys), y=y)
y = y + 15
numKeys = propNumKeys() - 1
for ( i = 0 , numKeys) {
propName = propGetKeyByIndex(index = i)
propType = propGetType(propName)
SubTitle("#"+String(i) + " property: '" + propName + "', Type = " + String(propType) , y=y)
y = y + 15
for(j=0, propNumElements(propName) - 1) {
SubTitle("element #" + String(j) + ", size = " + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + ", Value = " + String(propGetAny(propName, index=j)), y = y)
#SubTitle("element #" + String(j) + " size = " + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + ", Value = " + String(propGetAny(propName, index=j)), y = y)
y = y + 15
}
}
return last
})
ScriptClip(function[](clip c) {
a = propGetAsArray("s")
y = 100
x = 400
SubTitle(string(a.ArraySize()), x=x, y=y)
for(i=0, a.ArraySize()-1) {
SubTitle("["+String(i)+"]="+ String(a[i]),x=x,y=y)
y = y + 15
}
return last
})
# get int array one pass
ScriptClip(function[](clip c) {
a = propGetAsArray("s_int")
y = 440
x = 400
SubTitle("Array size=" + string(a.ArraySize()), x=x, y=y)
y = y + 15
for(i=0, a.ArraySize()-1) {
SubTitle("["+String(i)+"]="+ String(a[i]),x=x,y=y)
y = y + 15
}
return last
})
# get float array one pass
ScriptClip(function[](clip c) {
a = propGetAsArray("s_float")
y = 440
x = 200
SubTitle("Array size=" + string(a.ArraySize()), x=x, y=y)
y = y + 15
for(i=0, a.ArraySize()-1) {
SubTitle("["+String(i)+"]="+ String(a[i]),x=x,y=y)
y = y + 15
}
return last
})
# get string array
ScriptClip(function[](clip c) {
a = propGetAsArray("s_string")
y = 440
x = 000
SubTitle("Array size=" + string(a.ArraySize()), x=x, y=y)
y = y + 15
for(i=0, a.ArraySize()-1) {
SubTitle("["+String(i)+"]="+ String(a[i]),x=x,y=y)
y = y + 15
}
return last
})
AviSynth 3.7.1: allow propGetXXX property getter functions called as normal functions, outside runtime. By default frame property values are read from frame#0 which index can be overridden by the offset parameter.
Example:
Colorbars()
PropSet(last, "hello", 1) # Set to 1 for all frames
# Override to 2 with runtime function except for frameNo=1
ScriptClip("""if(current_frame!=1) {propSet("hello",2)}""")
n0 = propGetInt("hello") # same as propGetInt("hello",offset=0)
# or get the frame property from the Nth frame
n1 = propGetInt("hello",offset=1)
n2 = propGetInt("hello",offset=2)
# n0 and n2 is 2 (overridden in runtime)
# n1 will be 1 (keeps global setting)
SubTitle("n0/n1/n2=" + "{n0}/{n1}/{n2}".Format)
Deleting properties¶
Deletes specific properties or all property entries
propDelete¶
propDelete(clip, string)
Deletes a property by name. If property does not exist, do nothing.
clip (required) specifies clip.
string (required) or string array: key_name (case sensitive) specifies the
name of the parameter to delete
a regex expression, starts with "^", ends with "$"
a wildcard name specifier (contains
*
)
Example:
ScriptClip("""propDelete("my_spec_prop")""")
propDelete("_*") # deletes all properties starting with "_"
propClearAll¶
propClearAll(clip)
Clears all properties for a given video frame
clip (required) specifies clip.
Other property functions¶
propShow¶
This debug filter lists frame properties on screen. Listing appears as a name = value list and can be filtered
See here: propShow.
propGetDataSize¶
propGetDataSize(clip, string key_name [, integer "index", integer "offset"])
returns the size of the string or underlying data array
propNumElements¶
propNumElements(clip, string key_name [, integer "offset"])
returns the array size of a given property. 1=single value
propNumKeys¶
propNumKeys(clip, [, integer "offset"])
returns number of entries (keys) for a frame
propGetKeyByIndex¶
propGetKeyByIndex(clip, integer "index" [, integer "offset")
returns the key name for the Nth property (zero based, 0<=index<propNumKeys)
propGetType¶
propGetType(clip, string key_name [, integer "offset"])
returns the type of the given key
unset: 0
integer: 1
float: 2
string: 3
clip: 4
frame: 5
propCopy¶
propCopy(clip, clip [,bool "merge"], [,string[] "props"], [,bool "exclude"]
Copies the frame properties of the second clip to the first.
Parameter merge
(default false):
when false: exact copy (original target properties will be lost)
when true: keeps original properties, appends relevant properties from source but overwrite if a parameter with the same name already exists.
- Parameter
props
a string or string array:
name of the parameter to copy
a regex expression, starts with "^", ends with "$"
a wildcard name specifier (contains
*
)
Parameter exclude
when true specify that the property list is a negative list.
Example:
PropCopy(a) # make all properties the same with of clip a
PropCopy(a, merge=true) # Adds new properties from clip a, overwrites if already exists
# Add properties from clip "a" which end with "1" or "2"
b.PropCopy(a, merge=true, props=["*2","*1"])
# Add properties from clip "a" where not started with "_"
b.PropCopy(a, merge=true, props="_*", exclude = True)
# same with regex
b.PropCopy(a, merge=true, props="^[^_].*$")
# erase all, then copy all, except listed ones
propCopy(org,props=["_Matrix", "_ColorRange"], exclude = true)
Changelog¶
Version |
Changes |
---|---|
3.7.4 |
wildcard and regex support in props parameter
for propDelete, propShow, propCopy
add "props" parameter to propShow as well
|
3.7.2 |
exclude parameter for negative list
|
AviSynth 3.7.1 |
allow propGetXXX called outside
runtime functions
add propCopy
|
AviSynth 3.7.0 |
add propGetType |
Back to Internal functions.
$Date: 2025/03/04 12:20:00 $