No Deinterlacing When AViSynth Trim Used

Here you can submit bugreports
Post Reply
graham728
Posts: 82
Joined: Sat Oct 13, 2018 10:54 pm

No Deinterlacing When AViSynth Trim Used

Post by graham728 »

Hi,

I've just updated to the latest version 1.4.0

I use a AVISynth node to trim a few seconds from the start and end of files. This is then passed over to a deinterlace node, then to a H264 1080p encoder.

I've noticed that in 1.4.0 the outputted H264 1080p files are no longer being deinterlaced. See screengrabs below.

The inputted files are AVC Intra 100 1080i MXF.
Attachments
Deinterlace Node.png
Deinterlace Node.png (17.25 KiB) Viewed 14242 times
1.png
1.png (108.21 KiB) Viewed 14251 times
2.png
2.png (99.06 KiB) Viewed 14251 times
1080p.png
1080p.png (240.52 KiB) Viewed 14251 times
emcodem
Posts: 1812
Joined: Wed Sep 19, 2018 8:11 am

Re: No Deinterlacing When AViSynth Trim Used

Post by emcodem »

Hi graham,

sorry for the delay, i thought @FranceBB will be very interested in this because all avisynth stuff is his baby but i guess it is too hot in italy currently to turn on PC's in the living room ;-)

Looks like the checkbox "clear media properties in the custom avisynth processor" is the guilty one here. If you uncheck that one, it should work as expected. @FranceBB if you implemented this, may you reconsider the design please? Why is there a checkbox that is by default on instead of e.g. just the default example text having this line there?
emcodem, wrapping since 2009 you got the rhyme?
User avatar
FranceBB
Posts: 265
Joined: Sat Jun 25, 2016 3:43 pm
Contact:

Re: No Deinterlacing When AViSynth Trim Used

Post by FranceBB »

Hey guys,
yes it's very hot here and I can barely sleep at night despite having 2 fans both at 100% pointed directly towards my bed.
Hopefully August will be over soon... hopefully...
Still, 39°C is better than last year when we had peaks of 42°C, so I can't complain.
As for Graham's problem, are you actually sure to be running the latest version, namely FFAStrans 1.4.0.7?
This is what I get by clicking the "About" button:

Image

In other words:
Workflow manager (FFAStrans.exe, x64) 1.4.0.100
Workflow processor (FFAStrans_Queuer.exe, x64) 1.4.0.101
REST-API Service (rest_service.exe, x64) 1.4.0.76

The reason why I'm asking is that the screenshot you showed when you clicked on the Custom Avisynth Script looks very much like FFAStrans 1.3.1 which is the last version to use the old behavior before frame properties were introduced.
In FFAStrans 1.4.0 (any version of it, including the latest stable release) you would see an additional box in the Custom Avisynth Script next to "auto-adapt color space" which is "Clear media properties":

Image

Link to FFAStrans 1.4.0.7 Stable: https://github.com/steipal/FFAStrans-Pu ... 1.4.0.7.7z

What's happening in FFAStrans 1.3.1
In your workflow, you're indexing, trimming, deinterlacing and then delivering the output A/V Stream to the H.264 encoder.
Each node gets in input what the previous node outputted and in your case the deinterlacing node is set to "Autodetect" which means that it will use the metadata to understand whether the input is TFF, BFF or progressive instead of checking the actual content of the stream.
Unfortunately for you, the output of Trim() doesn't really carry any metadata, so the deinterlacing node assumes that it's dealing with a progressive stream and doesn't really do anything to deinterlace it.
The encoding node at that point, the one that is supposed to encode to H.264, takes the still-interlaced stream and encodes the fields as if they were progressive, thus producing a completely wrong output.

Workaround in FFAStrans 1.3.1
By changing the deinterlacing node from "Autodetect" to "Analyze" the filter is gonna analyze the actual stream coming out from Trim() and then decide whether it's TFF, BFF or progressive.
In your case, it will almost definitely detect it to be interlaced and perform the deinterlacing correctly. :)

Image

By the way, I suggest you to change YADIF to BWDIF as it produces a far better output at roughly the same speed. ;)

Image


Workaround in FFAStrans 1.4.0
FFAStrans 1.4.0 uses frame properties, which means that - as long as the indexer is populating everything correctly - the metadata will be carried through the various nodes. In the Custom Avisynth Script untick the "Clear media properties" tickbox and this will make them be passed through all the way to the deinterlacing node and then to the encoding node. :)
graham728
Posts: 82
Joined: Sat Oct 13, 2018 10:54 pm

Re: No Deinterlacing When AViSynth Trim Used

Post by graham728 »

Hi Thanks Both,

Frances - The screenshots in my first post are from 1.3.0 as I've been using that version for a little while. It's bug free for all the workflows I need it for, so I've been happy to continue using it. I shut down 1.4.0 and did the screenshots in 1.3.0.

When I ported all the workflows to 1.4.0 I noticed the deinterlacing issue.

I've tried changing the node to 'analyse' fields and to BWDIF leaving Clear Media Properties set to True.

Unfortunately, I'm still seeing the same issue of the files not being deinterlaced as they were being in 1.3.0

The fix of setting 'Clear Media Properties' to False does result in deinterlaced files. See screenshots.

Is it safe to set Clear Media Properties to False?
Attachments
Clear Media Properties Off.png
Clear Media Properties Off.png (118.84 KiB) Viewed 12698 times
Clear Media Properties On - Analyse Fields.png
Clear Media Properties On - Analyse Fields.png (106.18 KiB) Viewed 12698 times
User avatar
FranceBB
Posts: 265
Joined: Sat Jun 25, 2016 3:43 pm
Contact:

Re: No Deinterlacing When AViSynth Trim Used

Post by FranceBB »

Yes it absolutely is safe as you're preserving the metadata inside Avisynth.
You're just using the Trim() function and nothing special so it's totally fine.
In general you may wanna leave "Clear Media Properties" unticked (i.e set to false) unless you're modifying things yourself inside the frameserver.

Let's take the following scenario: you have a PQ input and you wanna convert to HLG.
In this case, in 1.4.0, you would have to populate the frame properties yourself to tell the filter_builder what you've done so that it knows what to do when it creates the filterchain for the encoder in the encoding node.
For instance, here I'm telling the filter_builder that I've already converted to BT2020 HLG Limited TV range so that it doesn't have to do it:

Code: Select all

LoadPlugin("%s_ffastrans_dir%\Processors\avs_plugins\AVSCube\x64\vscube.dll")
LoadPlugin("%s_ffastrans_dir%\Processors\avs_plugins\avsresize.dll")
my_lut="%s_ffastrans_dir%\Processors\avs_plugins\LUTs\WarnerBros_PQToHLG_MaxCLL_%s_my_nits%.cube"

#Getting rid of frame properties
propClearAll(m_clip)

#Bring everything to RGB Planar 16bit Narrow Range
AssumeFrameBased()
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)

#From PQ to HLG with 16bit precision
Cube(my_lut, fullrange=1, interp=1)

#From RGB 16bit planar Narrow Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P10", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)

#Clipping 
Limiter(min_luma=64, max_luma=940, min_chroma=64, max_chroma=960)

#Workaround for the filter builder
AssumeFieldBased() #workaround for filter builder in 1.3.1
propSet("_FieldBased", 0) #progressive
propSet("_ColorRange", 1) #Limited TV Range
propSet("_Matrix", 9) #BT2020
propSet("_Transfer", 18) #HLG
propSet("_Primaries", 9) #BT2020

m_clip=last

# The following MUST be the last line of your script
Return m_clip

In your case however you're just trimming, so you're not changing any of the frame properties, therefore it's totally fine to pass them through to the next node and if anything that's the correct behaviour. :)
emcodem
Posts: 1812
Joined: Wed Sep 19, 2018 8:11 am

Re: No Deinterlacing When AViSynth Trim Used

Post by emcodem »

I can add that we discussed about why the "Clear media props" checkbox even exists and why it is on by default. The intention is to allow upgrading from older versions to 1.4 without having to change the existing workflows as usual (1.4 ships the shiny new avisynth dll that supports "frame properties"). So the thinking is that any script that was written before avisynth "frameprops feature" was introduced, needs to use propsclearall() to continue working after upgrading the underlying avisynth dlls...

In other words clear frameprops checkbox in the custom avisynth processor is "true" by default only to support old scripts and it should not be on by default for new scripts.
emcodem, wrapping since 2009 you got the rhyme?
graham728
Posts: 82
Joined: Sat Oct 13, 2018 10:54 pm

Re: No Deinterlacing When AViSynth Trim Used

Post by graham728 »

Thanks - emcodem. I'm not sure I fully understand the above.

Do I have to manually toggle off this box across all the nodes/workflows when I upgrade?
emcodem
Posts: 1812
Joined: Wed Sep 19, 2018 8:11 am

Re: No Deinterlacing When AViSynth Trim Used

Post by emcodem »

Yes and no, it depends on the case, depending on the avs plugins you use, the checkbox can do good thing or bad things for you.
Obvisouly for deinterlacing with YADIF it needs to be unchecked.

Again, the reason why it is "checked" by default is that @FranceBB thought that this way you can upgrade without the need to change all avs processors but looks like this is not the case. I'm suer Frankie has something to say to that?
emcodem, wrapping since 2009 you got the rhyme?
User avatar
FranceBB
Posts: 265
Joined: Sat Jun 25, 2016 3:43 pm
Contact:

Re: No Deinterlacing When AViSynth Trim Used

Post by FranceBB »

emcodem wrote: Tue Dec 10, 2024 12:58 pm I'm suer Frankie has something to say to that?
Other than "I hate frame properties"?
No but seriously and jokes aside, unfortunately when Avisynth introduced frame properties on top of clip properties, it was a bit of a storm. In theory frame properties are great: they're populated by the indexer when you index a file and passed through the filterchain so that each filter is aware of what it's dealing with and can perform the appropriate action. Also, in theory, those are then passed all the way down to the encoder, which means that it also knows what it's dealing with. In the case of FFAStrans, before you had two options:

A) you dealt with everything yourself and then only really used the encoder to encode

B) you leveraged on the filter builder to do stuff

There was no in between. Let me explain.
FFAStrans deals with every file that is thrown at it as if it were to solve one problem at a time and this is done by something called "the filter builder" (i.e filter_builder.au3). Once a file is submitted to FFAStrans, it gets analysed by a combination of ffprobe, exiftools and Mediainfo and then, once the filter builder knows what's is dealing with in input and what the target output is, it "builds" the "filterchain", hence the name. Such a component goes through the problems one at a time to check whether it's interlaced or not, what the frame rate it, what the resolution is, what the chroma location is, what the chroma sampling is, what the colormatrix, transfer and primaries are, what the bit depth is etc and what the target needs to be to then build a bridge from the input to the target. It's based on a huge series of rules, it's several lines long and it's a marvelous piece of code that Grandmaster Steinar wrote and improved over the years. Anyway, that's basically what happens when you put an encoding node there in a workflow. In the former FFAStrans version this would be option B, i.e let the filter_builder take care of it. Now, given that there weren't frame properties in Avisynth and given that clip properties only really carried a limited subset of information, we had to work around that. In particular, Avisynth wasn't passing anything down the line to FFMpeg in terms of properties, but that's because historically Avisynth was supposed to be the frame server doing all the various transformations and then have its uncompressed audio and video stream go to an encoder. For instance, I often use it to encode with x264 and create the raw_video.h264, with BePipe + NeroAAC to create the raw_audio.aac and MP4Box to create the final_output.mp4 using a BAT. The idea being that no other transformation should be needed on the Avisynth output. Anyway, this isn't exactly the case with FFMpeg. As ironic as it may sound, FFMpeg is a collection of tools, so not only it can call encoders like x264 via libx264, FDK AAC etc and muxers like the MP4 muxer as part of lavf, but it's also a frameserver itself as it can perform different kinds of filtering via the filtercomplex as it includes things for scaling in sws, it includes z.lib, etc. Suddenly we have a situation which the original Avisynth developers didn't envision: having the output from Avisynth go into another frameserver before being converted again and going into the actual encoder. This is what happens in FFAStrans. So... if the filter_builder is meant to create a filterchain in FFMpeg and it does it based on the input but the input is an Avisynth script which doesn't have any properties at all, how does it know what it's receiving and where it needs to go? Well... simply put: it doesn't. What we did was a huge implementation of passing properties around, so basically when you had an input, FFAStrans was gonna analyse it anyway before going through the indexing step (i.e before going through the A/V Decoder) and then once you inserted a filter (I'm talking about one of the actual filters built into FFAStrans) we were gonna update the properties internally 'cause I mean we knew what was gonna happen and what the settings were gonna do on the input. Like, if you were to insert a deinterlacing node with BWDIF 2x and the input was interlaced, we knew that it was gonna bob deinterlace it, so we updated those info under the hood so that once you got to the encoding node, the filter builder knew that it was dealing with a progressive source. This obviously was only possible for the built-in filters, but not with the custom Avisynth scripts. Like, suppose you add a LinearTransformation filter to go from BT2020 HLG to BT709 SDR, then we would know that we were dealing with BT709 SDR, but if you did it yourself in a custom Avisynth script cause you wanted to use Reinhard Tonemapping rather than a LUT, then we wouldn't have had any way to know that the output was now BT709 already and that the filter_builder didn't have to convert it before calling the encoder. This led us to create a tickbox in the custom Avisynth script called "adapt" (I don't remember the exact name but it started with "adapt") in FFAStrans 1.2.0 come 2021 that basically told the filter builder "don't do anything, I've got everything under control" and only really do the straightforward things that could be inferred by the clip properties like the chroma sampling conversion, the resolution conversion etc, but definitely nothing matrix/transfer/primaries related etc. This obviously wasn't ideal, so either you had to go with option A, do everything in custom Avisynth script to give the filter builder something perfect and then encode or just not use those custom Avisynth scripts and let the filter builder do everything. Obviously one could have also just created a workflow like:
watchfolder -> A/V Decoder -> Deinterlacing node -> Custom Avisynth Script (denoise) -> Encoder -> Delivery
and left the "adapt" option unticked to let the filter builder do its thing as you were not gonna change other properties of the video, just denoising it, hence why the adapt was a tickbox that could be ticked and unticked. Once again, this whole thing wasn't ideal because let's assume for a moment that your source is 4:2:0 with chroma_location "top_left" but your denoise only works in 4:2:2 interleaved (i.e YUY2). In your Avisynth Script you could have just used a simple ConverttoYUY2() then the denoise like SpatialSoften(4, 4, 8) and then back to 4:2:0 with ConverttoYV12(). You didn't tick the "adapt" so you would still be able to take advantage of the filter_builder converting everything else to your destination like resolution changes, matrix/transfer/primaries etc and everything will be hunkydory, right? Well, not quite. You see, the filter_builder will do that with the information it has from the input and adjusted as per the last known internal node (the deinterlacing one), but once you inserted the deinterlacing node you just changed the chroma location from top_left to left in the YV12-YUY2-YV12 roundtrip without telling the filter_builder, so it will still assume a top_left chroma location and the output will be wrong. Frame Properties were introduced to solve EXACTLY this problem. Suddenly, the filter_builder was no longer blind, it wasn't kept in the dark about what it was receiving as Avisynth finally had a way of telling exactly what was passing and this was a game changer. We removed all the old logic and allowed Avisynth to talk directly to the filter builder which not only simplified the handling of internal filters but even the custom Avisynth script now allowed people to truly have an hybrid approach that was neither A nor B but something in between, I'll call it option C:

C) do something I really care about myself and let the filter builder do the rest


This is where we are now with FFAStrans 1.4.0.xx, so this brings the question: what's with the "clear frame properties" tickbox? If frame properties are great, then why would you wanna remove them and not use them in the first place?

Well... the answer is complicated and it would it would make this post from "long" to "downright unreadable", so in a nutshell, carrying frame properties isn't always a good thing. As we're transitioning from clip properties to frame properties, we're in a pretty dim situation right now. Some filters embraced frame properties and use them to adjust their settings which is something you not always want especially if you're telling a function what to do explicitly, some other don't update frame properties after they've done their own things but just carry them over, which is bad as it then falls to the user to change them and some others don't even pass them over as they were made with very old versions of Avisynth in mind like those for Avisynth 2.5 (we're currently at 3.7.3) so again it falls to the user to populate them manually with PropSet(). Unfortunately, there's no simple way to look at it and there isn't a simple solution that fits everything, but essentially we tried offering people the possibility to do everything regardless of frame properties and, given that they didn't exist up until recently, turning on the "clear frame properties" by default was in theory a mechanism to protect people from suddenly having their functions doing other things rather than what they thought they were doing, but obviously this backfired in some situations. The migration to frame properties is there to stay and I'm sure it will bring more benefits in the long run, but at this moment in time there sure are a lot of headaches, which is why I often joke about it by saying "I hate frame properties". Truth to be told, I don't hate them, I'm sure they're gonna bring so many benefits and they've already been a game changer for lots of my workflows that went from doing literally everything myself to leveraging on the filter builder more and only address manually the things I truly care about. The only thing is that, unlike VapourSynth which was born with them and therefore everything is aware of them, in Avisynth they have just been introduced and it will take a long time for everything to be aware of them and also, realistically, some filters will never be updated so you're gonna need some workaround anyway, but this just shows how long of a journey it's been for this amazing 24 years old frameserver. ;)
Post Reply