View Full Version : Performance hit from Crop()?


Monk_Zero
10th January 2013, 07:19
I'll start by saying I'm still an ignorant novice who is figuring out I've been doing things wrong with Avisynth scripts all the time so there's tons of room to improve, so any suggestions are more than welcome no matter how basic.

I've been refining a script I used on a single threading machine for my new multithreading laptop (hardly a powerhouse) and it's highlighted areas for improvement. I fixed lots of them but I've run across one that seems wrong but I can't fix it.

SetMemoryMax(512)
SetMTMode(5,4)
PluginPath = "C:\Program Files (x86)\MeGUI\tools\avisynth_plugin\"
AviSource("C:\New folder\Suburban 07.avi")
Crop(6, 0, -8, -0, align=true)
AssumeTFF()
TDecimate()
SelectEven()
SetMTMode(2)
ConvertToYV12(interlaced=true)
QTGMC(Preset="Slow")
LanczosResize(640,480)
Distributor()

My source is interlaced NTSC television capped via SVideo at 720x480 YUY2 4:2:2 with Lagarith and usually movies so I bring them down to 23.976. Everything works with multithreading so far (near 100% utilization now during both first and second pass encoding in MeGUI, which is a great improvement). But I'm running into a huge performance hit from Crop that doesn't seem right to me. When in the script, Crop applies a 25% hit in the overall frames per second almost exactly. Using the above script as a baseline:
Above script with Crop(6, 0, -8, -0, align=true) commented out
First pass 17.35 fps
Second pass 15.60 fps

Above script with Crop(6, 0, -8, -0)
First pass 13.02 fps
Second pass 11.14 fps

Full original script with Crop(6, 0, -8, -0, align=true)
First pass 13.10 fps
Second pass 11.11 fps

Above script but with Distribution() commented out
First pass 14.59 fps
Second pass 12.96 fps

It seems like a problem for a function like Crop to have such a large impact. Cropping should reduce my overall workload by giving me a smaller frame to work with but that just isn't the case. I've also tried placing it after SetMTMode(2) and in other various locations and the performance hit is slightly worse but otherwise negligible. Unfortunately, cropping is necessary as you can see I've got a blue line and junk on the sides of many captures and several will be letterboxed so it's a necessity most of the time. I'd really like to have the non-Crop speed if I can because it makes a real difference if doing a full movie.

Is there a way to use Crop() so I don't get such a large performance hit? Alternately, is there a way to use one of my other functions to get the same end result of cropping the image but without the huge performance hit? Or is there another style of Crop function I could use?


Also, it's become clear to me that TDecimate() and SelectEven() seem redundant. Which one is more appropriate? I can remove either of them and I can't really see a difference and the performance hit is negligible. I'd really like the cleanest script I can get though so if I can get rid of a step I'd like to.

And, I'd definitely recommend tips that would make either my script more efficient or make my end result look better. Here's a small example source and the end result in mkv format.
Source: http://www.mediafire.com/?0fycjpnher9qztf (audio is out of sync, which is expected and something I correct later)
Encode: http://www.mediafire.com/?lbaax93ntad9vio

Thanks!

Groucho2004
10th January 2013, 10:10
You have a performance hit because the frame is not mod4 after cropping.
Changing "Crop(6, 0, -8, -0)" to "Crop(8, 0, -8, -0)" for example will fix it.

Don't just throw in the "Distributor()" call at the end. x264 applies this call already. You are just increasing the number of threads unnecessarily which reduces efficiency.

You can test the speed of your script with AVSMeter (http://forum.doom9.org/showthread.php?t=165528) if you want to exclude the encoder from the equation.

Didée
10th January 2013, 10:29
More important than any possible performance hit is that the processing chain of your script is just wrong. The source is standard 3:2 pulldown (aka "telecine"). You must not deinterlace - no tdeint, no QTGMC. Instead you need to apply standard pulldown removal, aka IVTC ("inverse telecine").

AviSource(...)
TFM()
TDecimate()
Spline36resize(60,480, 6,0,-8,-0)
return(last)

If you want to use QTGMC nonetheless because you like its enhancement- and denoising side effects, then you can put QTGMC(InputType=1) after the TDecimate call. (InputType=1 tells QTGMC that it is working on a progressive clip).

Monk_Zero
10th January 2013, 21:42
You have a performance hit because the frame is not mod4 after cropping.
Changing "Crop(6, 0, -8, -0)" to "Crop(8, 0, -8, -0)" for example will fix it.

Don't just throw in the "Distributor()" call at the end. x264 applies this call already. You are just increasing the number of threads unnecessarily which reduces efficiency.

You can test the speed of your script with AVSMeter (http://forum.doom9.org/showthread.php?t=165528) if you want to exclude the encoder from the equation.

Ah, I had gotten warnings that the width had to be Mod2 but didn't know there was a performance impact if it wasn't Mod4. I ran AVSMeter (thanks for pointing me to it) and here are my results, run twice for each option:
Script as above:
Average FPS 15.62-19.17

Script with Mod4 Crop
Average FPS 34.25-34.65

Script with Crop commented out
Average FPS 32.97-33.71

So that's clearly the problem and the impact is huge. To help me understand, the wiki seems to say that YUY2 is Mod2 and I get errors thrown up if I don't have a Mod2 value but I don't get a warning if it isn't Mod4. And it does work, only it seems to have to work twice as hard. Should there be a note in the wiki about the performance impact if you use Mod2 values in YUY2? http://avisynth.org/mediawiki/Crop

But then that leaves me with a problem. I have garbage on the side of the capture but I don't want to crop visible image which would be necessary if I have to use Mod4 values for Crop(). It seems that there's two solutions but I don't know if they can be done.
a) Can I pad the image with artificial pixels on the side so that I can crop with a Mod4 value but not cut out visible image? Like change it from a 720 width frame to a 722 width frame and then Crop with Crop(8...) and achieve only the same result as a Crop(6...) from the original frame?
b) Can I "paint" the pixels black and just have a visible black border? That would be preferrable to cropping out visual information for my goals.

Any help on that or other alternatives would be most welcome.

Also, I included a test pass with Distribution commented out just in case that was the problem. In my case, Distributor provided a performance hit and otherwise didn't seem to add value. I'll remove it going forward.

More important than any possible performance hit is that the processing chain of your script is just wrong. The source is standard 3:2 pulldown (aka "telecine"). You must not deinterlace - no tdeint, no QTGMC. Instead you need to apply standard pulldown removal, aka IVTC ("inverse telecine").

AviSource(...)
TFM()
TDecimate()
Spline36resize(60,480, 6,0,-8,-0)
return(last)

If you want to use QTGMC nonetheless because you like its enhancement- and denoising side effects, then you can put QTGMC(InputType=1) after the TDecimate call. (InputType=1 tells QTGMC that it is working on a progressive clip).

Thanks for helping me get it on the right track. Taking QTGMC out of the script, this is what I've got. Does that have things in the correct chain?
SetMemoryMax(512)
SetMTMode(5,4)
PluginPath = "C:\Program Files (x86)\MeGUI\tools\avisynth_plugin\"
AviSource("C:\New Folder\Suburban 07.avi")
TFM()
TDecimate()
SetMTMode(2)
ConvertToYV12(interlaced=true)
Spline36resize(640,480, 6,0,-8,-0)
return(last)

Running this script, I've got some interlacing artifacts left over.
http://i48.tinypic.com/2mhe7is.png

Here's an example clip using the original sample for comparison. Any way to reduce or eliminate those leftover interlacing effects using this method?
http://www.mediafire.com/download.php?zxtlrvopo8ye5u6

I really appreciate the help so far. It's hardly a surprise to me that I was doing things wrong. :)