Working With Fields and Frames
Many video filters require progressive video to work properly. Since both fields of an interlaced video stream are usuall stored in a single frame (frame based) in the digital domain, in order to properly process some video you'll have to be able to identify interlacing and possibly know how to separate it into individual fields, either in a single clip or one for the top field and another for the bottom. Once processed you may also need to weave top and bottom fields back together.
Interlacing and Field Dominance
The most accurate way to identify interlaced video is to visually inspect it. To do this with AviSynth you can use a program like VirtualDub to open your script and simply examine individual frames in areas of motion. Since interlaced fields are pictures from different moments in time there should be clear indications that the fields don't line up properly. Once you know you have interlaced video you also need to consider the field order. Depending on the source of the file, either the top or bottom field may be dominant (ie display first). This must be consistent throughout the file. If you're not sure of a clip's field dominance you can use the SeparateFields filter detailed below to examine individual fields, with either the top or bottom field displayed first. If you've set the field dominance incorrectly you'll get jerky motion. You'll often see field dominance referred to as field order, which is the convention this guide uses for the most part.Field Polarity
In addition to field order, you may need know, or even change, the polarity of a field. Polarity refers to whether a field is the top (lines 0, 2, 4, ....) or bottom (lines 1, 3, 5, ....) field in a frame. In some cases you may even be working with field based video, meaning each field is stored as an individual image but still displayed as a single interlaced field. In some cases you may even need to convert frame based video, which has two fields stored in a single frame, to field based (field separated) video for processing, or even deinterlacing.Spatial vs. Temporal Filtering
Some filters work within a frame. A resize filter, for example, only considers the contents of a single frame at a time. This is also referred to as a 2D or 2 Dimensional filter. Other filters analyze multiple frames to process each one. These are temporal, or time based, filters. Some filters even process both spatially and temporally, and are sometimes referred to as 3D or 3 Dimensional filters. When your source is interlaced you have to consider how this will affect filtering. For spatial filters there's usually a comparison of adjacent pixels, meaning you may need to separate an interlaced clip so that each field is completely separate. For both spatial and temporal filtering you may even have to create separate clips, each containing only top fields or bottom fields from the video. Fortunately AviSynth includes all the tools you need to perform these tasks with minimal effort.Telecine
If you deal with NTSC video you'll want to familiarize yourself with how 24fps film is converted to 29.97fps interlaced video. You can read more about this in our Digital Video Fundamentals guide on Frames and Framerates, as well as our guide on IVTC (Inverse Telecine).You can use AviSynth to perform IVTC on telecined video, re-creating the original progressive film frames. This will require that you understand the use of SeparateFields, as well as one or more IVTC plugins. See the section on TIVTC for more information.
AssumeTFF
AssumeTFF (clip)
Argument | Type | Default | Req | Description |
clip | clip | last | The clip to set field order for |
AssumeTFF sets the field order to Top Field First. When working with interlaced video, it's often necessary to manually specify the field order as AviSynth doesn't always get accurate information from the source. This is particularly true when using filters that work in 3 dimensions (height, width, time).
Example Code
Set field order to Top Field First for video source:AviSource("D\Some Directory\SomeFile.avi").AssumeTFF()
When To Use It
When loading interlaced video you should assume that AviSynth needs to be told what the field order should be. If you have Top Field First video use AssumeTFF. For Bottom Field First video use AssumeBFF.AssumeBFF
AssumeBFF (clip)
Argument | Type | Default | Req | Description |
clip | clip | last | The clip to set field order for |
AssumeBFF sets the field order to Bottom Field First. When working with interlaced video, it's often necessary to manually specify the field order as AviSynth doesn't always get accurate information from the source. This is particularly true when using filters that work in 3 dimensions (height, width, time).
Example Code
Set field order to Bottom Field First for video source:AviSource("D\Some Directory\SomeFile.avi").AssumeBFF()
When To Use It
When loading interlaced video you should assume that AviSynth needs to be told what the field order should be. If you have Top Field First video use AssumeTFF. For Bottom Field First video use AssumeBFF.SeparateFields
SeparateFields (clip)
Argument | Type | Default | Req | Description |
clip | clip | last | The clip to separate into individual fields. |
SeparateFields returns a clip with frames made up of individual fields from an interlaced clip. Field dominance will be read from the source. If it's incorrect you can use AssumeTFF or AssumeBFF before SeparateFields to correct it. The picture below shows an interlaced frame both before and after SeparateFields. SeparateFields uses the clip's field order to determine which field to put first in each frame so a TFF clip would start with the top field of frame 0. It's generally recommended to use either AssumeTFF or AssumeBFF before SeparateFields to ensure that the proper field order is used.
Although the resulting clip appears progressive, AviSynth still knows they're interlaced fields. The difference is that it's a field based clip instead of frame based. The reason for handling it this way is to maintain each field's polarity. This way AviSynth can pass the information to another program, like a field based encoder, or combine the fields properly into an interlaced frame using the Weave filter. If you were to view the script's output as a progressive stream at this point you'd notice that the image bobs up and down because every other field is offset 1 line (spatially).
Example Code
Proces interlaced video with a spatial filter:SeparateFields().SomeSpatialFilter()
When To Use It
When you need to apply a spatial filter for something like resizing (changing resolution) or certain noise related tools you should separate the fields so the filter can operate on individual images, rather than two images mixed together. If you're using filters that operate both spatially (within each frame) and temporally (across multiple frames) you may need to use SelectEven and SelectOdd to completely isolate top and bottom fields from each other.Weave
Weave(clip)
Argument | Type | Default | Req | Description |
clip | clip | last | Clip to weave into interlaced frames |
Weave combines fields from field based video (or field separated video) into interlaced frames. Although it's stored as individual fields rather than in pairs, AviSynth still keeps track of which is a top and which a bottom field. Field dominance is based on whether the top or bottom field for each frame comes first in the field based clip.
Example Code
Weave processed fields back into a frame based clip:SeparateFields().SomeSpatialFilter().Weave()
When To Use It
After you've separated fields into a field based clip and processed them spatially you'll probably need to return them to a frame based clip for an encoder or other program to accept. Use Weave to combine each pair of fields back into interlaced frames. Field polarity is preserved in field separated video, and used by Weave to reconstruct the original frames correctly.SelectEven
SelectEven(clip)
Argument | Type | Default | Req | Description |
clip | clip | last | Clip to return just even numbered frames from |
SelectEven returns a clip consisting of every even numbered frame in a clip. Since the first frame of a clip is numbered 0, this translates to return every other frame, starting with the first one. Although it can be used just as easily for progressive frames, it's primarily used after SeparateFields to create clips containing only top or bottom fields so they can be filtered separately.
Example Code
Create a clip from only the top fields of a TFF clip:TopField = SeparateFields().SelectEven()
Create a clip from only the bottom fields of a BFF clip:
BottomField = SeparateFields().SelectEven()
When To Use It
When you use filters that operate both spatially (within each frame) and temporally (across multiple frames) you may need to process the top and bottom fields separately. Use SelectEven and SelectOdd to do this once you've used SeparateFields to make your video field based. If a filter only processes spatially simply separating fields should be all that's necessary. If it processes only temporally no field separation should even be necessary.SelectOdd
SelectOdd(clip)
Argument | Type | Default | Req | Description |
clip | clip | last | Clip to return just odd numbered frames from |
SelectOdd returns a clip consisting of every odd numbered frame in a clip. Since the first frame of a clip is numbered 0, this translates to return every other frame, starting with the second one. Although it can be used just as easily for progressive frames, it's primarily used after SeparateFields to create clips containing only top or bottom fields so they can be filtered separately.
Example Code
Create a clip from only the bottom fields of a TFF clip:BottomField = SeparateFields().SelectOdd()
Create a clip from only the top fields of a BFF clip:
TopField = SeparateFields().SelectOdd()
When To Use It
When you use filters that operate both spatially (within each frame) and temporally (across multiple frames) you may need to process the top and bottom fields separately. Use SelectEven and SelectOdd to do this once you've used SeparateFields to make your video field based. If a filter only processes spatially simply separating fields should be all that's necessary. If it processes only temporally no field separation should even be necessary.Interleave
Interleave(clip1, clip2)
Argument | Type | Default | Req | Description |
clip1 | clip | * | Clip to get top fields from | |
clip2 | clip | * | Clip to get bottom fields from |
Interleave can be used to create a single interlaced clip from two progressive clips. As with all interlaced content, it's best to set field dominance manually after your interlaced clip is created.
Example Code
Put top and bottom fields that have been processed separately back together:Interleave(TopField, BottomField).AssumeTFF()