View Full Version : Please critique my PAL->NTSC script!
Paul Curtis
29th May 2006, 22:41
Hello! Sorry to intrude.
Based on various bits of information that I've gleaned through searching the archives here, I've come up with the following script for converting hybrid PAL (i.e., video with the occasional film insert--mainly old BBC stuff) to NTSC:
---
mpeg2source("C:\Video\Disk1.d2v")
tdeint(mode=1,type=3,full=false)
import("C:\Program Files\AviSynth 2.5\plugins\MotionProtectedFPS.avsi")
assumefps(50.05)
motionprotectedfps(60)
assumefps(60000,1001)
lanczosresize(720,480)
converttoyuy2()
separatefields()
selectevery(4,0,3)
weave()
---
I am using:
AviSynth 2.5.6,
DGMPGDec 1.4.7RC2,
TDeint 1.0RC7,
MaskTools 1.5.8, and
Motion 12Dec05.
It seems to deliver pretty good results, but I'd be most grateful if anybody could suggest any reasonable tweaks or improvements. I'm not exactly an expert at this sort of thing, so it's entirely possible that I've missed something elementary--please don't be too harsh!
In particular, I'm wondering if I should do my resizing before or after the colorspace conversion. Does it make any difference?
(BTW, the "assumefps()" stuff is in there because, as far as I can tell, the MotionProtectedFPS script won't accept fractional framerates. If anybody can suggest a more elegant method of dealing with this, please feel free.)
Thanks in advance!
--Paul Curtis
actionman133
30th May 2006, 10:02
Actually, the ConvertToYUY2 is not necessary for a PAL-NTSC conversion. As a general rule, avoid colour space ocnversions unless absolutely necessary, and it's not necessary in this process.
Other than that, it is actually quite good, a nice high quality one. Although for higher (but much much much MUCH slower) quality, you could replace TDeint with MVBob () or SecureDeint () [part of MVBob ()]. I'm not too familiar with MotionProtectedFPS, since I prefer to use MVFlowFPS2 () within the MVtools set. It supports fractional framerates too, which I appreciate.
It's good as it is (I think all the filters are correctly ordered), but with some higher quality filters (particularly with a snail paced deinterlacer ;) ), it could be great!
:p
EDIT: Corrected my own error.
Paul Curtis
30th May 2006, 11:02
Actually, the ConvertToYUY2 is not necessary for a PAL-NTSC conversion. As a general rule, avoid colour space ocnversions unless absolutely necessary, and it's not necessary in this process.
It seems to be necessary for me, 'cause if I feed my MPEG encoder (Canopus ProCoder 2.0) with YV12 video, the levels come out wrong, and I have to apply ProCoder's 601 Correction filter to get them right again. I don't have this problem if I give it YUY2. I have no idea why this should be.
Other than that, it is actually quite good, a nice high quality one. Although for higher (but much much much MUCH slower) quality, you could replace TDeint with MVBob () or SecureDeint () [part of MVBob ()].
I did try MVBob(), but it's S L O W !
However, after further perusal of the archives, I decided to give EEDI2 (v0.9.1) a shot, like so:
---
mpeg2source("C:\Video\Disk1.d2v")
interp=separatefields().eedi2(field=-2)
tdeint(mode=1,full=false,edeint=interp)
import("C:\Program Files\AviSynth 2.5\plugins\MotionProtectedFPS.avsi")
assumefps(50.05)
motionprotectedfps(60)
assumefps(60000,1001)
lanczosresize(720,480)
converttoyuy2()
separatefields()
selectevery(4,0,3)
weave()
---
I honestly can't tell the difference, though in truth, I'm not entirely sure of what I should be looking for. Still, this actually seems slightly faster than TDeint(type=3) on my system, and it's supposed to give better results, so what the hell!
Thanks very much for your input!
--Paul Curtis
scharfis_brain
30th May 2006, 15:31
Actually, the ConvertToYUY2 is not necessary for a PAL-NTSC conversion. As a general rule, avoid colour space ocnversions unless absolutely necessary, and it's not necessary in this process.
In fact you MUST convert YV12 to YUY2 (or RGB24) before reinterlacing.
This conversion is only obsolete, if you are REALLY sure that the encoder accepts native YV12 without any internal conversion. Such encoders are eg. HcEnc, QUEnc and XViD.
All Commercial encoders I know of will only accept YUY2 and RGB24 correctly. Feeding them with interlaced YV12 will result (if they accept that) in destroyed chroma in moving areas (You'll see big chroma combing and stutter on the TV)
Based on various bits of information that I've gleaned through searching the archives here, I've come up with the following script for converting hybrid PAL (i.e., video with the occasional film insert--mainly old BBC stuff) to NTSC
This script will only work properly with true interlaced content.
It will turn the progressive (FILM) sequences into a jerky mess, because it tries to interpolate intermediate frames/motion where it not belongs to.
Hybrid sources are always problematic to convert.
I worked on a detection routine some months ago and it turned out to be pretty trick to do it automagically.
I suggest you either to use blending (convertfps) or a manual approach like this:
import("C:\Program Files\AviSynth 2.5\plugins\MotionProtectedFPS.avsi")
mpeg2source("C:\Video\Disk1.d2v")
a=tdeint(mode=1,type=3).motionprotectedfps(59.94)
b=tfm(pp=0).changefps(59.94)
x0=a.trim(0, 2000)
x1=b.trim(2001, 4789)
x2=a.trim(4790, 7892)
.
.
.
x?=b.trim(... , ...)
x0+x1+x2+...+x?
lanczosresize(720,480)
assumetff()
converttoyuy2()
separatefields().selectevery(4,0,3).weave()
Use the trim commands to switch between FILM (b) and VIDEO (a) scenes.
Paul Curtis
30th May 2006, 21:48
This script will only work properly with true interlaced content.
It will turn the progressive (FILM) sequences into a jerky mess, because it tries to interpolate intermediate frames/motion where it not belongs to.
Hmm. It doesn't seem all that bad to me when viewed on an interlaced monitor, but maybe that's because I come from the Land of the 3:2 Pulldown, and am therefore accustomed to jerky film!
Hybrid sources are always problematic to convert.
I worked on a detection routine some months ago and it turned out to be pretty trick to do it automagically.
I wonder how a hardware motion-compensated converter (like the Snell & Wilcox Alchemist) would deal with such material. Would the operator have to manually change the settings every time a film sequence came up? And how would one deal with mixed material (e.g., film/video crossfades, or film footage chromakeyed onto a video background)?
I suggest you either to use blending (convertfps)
Like so?
---
mpeg2source("C:\Video\Disk1.d2v")
interp=separatefields().eedi2(field=-2)
tdeint(mode=1,full=false,edeint=interp)
convertfps(60000,1001)
lanczosresize(720,480)
assumetff()
converttoyuy2()
separatefields()
selectevery(4,0,3)
weave()
---
From the example that you posted, should I take it that the YV12->YUY2 conversion is to be performed after resizing, and not earlier?
Also, it turns out that I was wrong about EEDI2 being faster than TDeint(type=3) on my machine--it just seemed that way at first. What should I look for, in determining whether it's worth the speed penalty?
Thanks very much!
--Paul Curtis
Paul Curtis
30th May 2006, 23:04
should I take it that the YV12->YUY2 conversion is to be performed after resizing, and not earlier?
This now seems to be a moot question, as I've just discovered that ConvertFPS() requires YUY2! So, here's my latest revision:
---
mpeg2source("C:\Video\Disk1.d2v")
interp=separatefields().eedi2(field=-2)
tdeint(mode=1,full=false,edeint=interp)
converttoyuy2()
convertfps(60000,1001)
lanczosresize(720,480)
separatefields()
selectevery(4,0,3)
weave()
--Paul Curtis
webwonk
23rd June 2006, 15:15
Pardon my ignorance, but Paul - what is the final frame rate of your latest version of the script?
I have to convert PAL 25 interlaced fps video to NTSC 29.97 progressive fps. Will your script do that?
Thanks to anyone who can provide an answer
actionman133
23rd June 2006, 17:12
No, it won't webwonk... it will convert interlaced PAL to interlaced NTSC.
Modifying Paul's original script, to get 29.97p, use this script:
mpeg2source("C:\Video\Disk1.d2v")
interp=separatefields().eedi2(field=-2)
tdeint(mode=1,full=false,edeint=interp)
converttoyuy2()
convertfps(60000,1001)
lanczosresize(720,480)
SelectEven ()
The change is in the SelectEven (). Instead of producing 59.94 fps and reinterlacing (which forms the last 3 lines of his script), it simply drops every second frame, reducing 59.94p to 29.97p, which is what you want...
webwonk
27th June 2006, 18:41
Almost there. I'm using the following script:
video = mpeg2source("C:\PAL\PAL.d2v")
interp=separatefields().eedi2(field=-2)
tdeint(mode=1,full=false,edeint=interp)
converttoyuy2()
convertfps(60000,1001)
lanczosresize(640,480)
SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
but Avisynth doesn't recognize separatefields. Any ideas?
webwonk
27th June 2006, 19:00
One other thing. I've always been schooled that when you decrease resolution, you use bilinear (e.g. 720x576 to 640x480) but when you increase resolution you use lanczosresize. Not to start a holy war, but what is the currently thinking on this?
buzzqw
27th June 2006, 19:31
:o ... ehmmm can these scripts be generalized for PAL<->NTSC (23.967/29.97) conversion ? HOW ?
thanks
BHH
actionman133
28th June 2006, 01:56
Here's your problem...
video = mpeg2source("C:\PAL\PAL.d2v")
interp=video.separatefields().eedi2(field=-2)
interp.tdeint(mode=1,full=false,edeint=interp)
converttoyuy2()
convertfps(60000,1001)
lanczosresize(640,480)
SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
The problem there was SeparateFields () didn't have a specified clip, so it was looking for the implicit Last. Last doesn't exist because you loaded your source into Video.
The same thing applies for TDeint. TDeint wasn't given a source, so I added interp to the beginning. Other than that, your script should be fine.
About bilinear and Lanczos... it's really a matter of taste. I always use bilinear when reducing because it's soft. Using a sharper resizer can make the video compression a nightmare because there is too much detail (when I reduce, I want compressibility, not quality).
For increasing resolution Lanczos is good. The spline resizers are supposed to be better (I think they are sharper but have less haloing on edges), although it's hard to tell the difference.
What is your output destination? Is it DVD, or staying on computer? I noticed your first script resized to 720x480 (DVD), then changed to 640x480 (computer)...
BuzzQ, you can just use webwonk's script, but if the source is 23.976 fps, it's probably not interlaced. If so, use this:
video = mpeg2source("C:\PAL\PAL.d2v")
video.converttoyuy2()
convertfps(60000,1001)
lanczosresize(640,480)
SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
If it's film content to be played on computer, I'd recommend that you don't convert the framerate, but leave it as it is.
chros
29th June 2006, 18:45
And what is the situation if the source is PAL 25 fps (including interlacing artifacts) and I want to create NTSC 23.976 fps ?
Thanks
MuttLover
6th July 2006, 16:01
About the handling of the Last builtin variable: You write:
video = mpeg2source("C:\PAL\PAL.d2v")
video.converttoyuy2()
convertfps(60000,1001)
lanczosresize(640,480)
SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
...
After video.converttoyuy2() is the value of last and the value of video the same? Also it seems to me like nothing happens to clip video after the video.converttoyuy2() statement, then it is used explicitly in the audiodub command. Isn't convertfps, lanczosresize, and selecteven all operating on the last clip, not the video clip?
I'm new to avisynth coding, and I'm trying to get my head around all of this. To my mind, the convertfps, lanczosresize, and selecteven statements should be preceeded with "video."
If you can clarify this for me I'd appreciate it. Apologies for being a bit off topic here.
foxyshadis
6th July 2006, 19:21
Actually to make that script correct all that's needed is AudioDub(audio), otherwise the script collapses to:
video = mpeg2source("C:\PAL\PAL.d2v")
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
and I seriously doubt that was the intention. When using AudioDub (or basically anything) without enough clips, it'll use last as the first like AudioDub(last, audio).
MuttLover
6th July 2006, 20:28
In the code fragment in question, where does last get assigned anywhere? The clip is named video, and video.converttoyuy2() is the final place that the clip named video is referenced until the audiodub(video, audio) line...my meaning being that the convertfps, lanczosresize, and selecteven would essentially be operating on a null clip (last) and the clip named video would not be resized, etc.
foxyshadis
6th July 2006, 20:44
video = mpeg2source("C:\PAL\PAL.d2v")
video.converttoyuy2()
convertfps(60000,1001)
lanczosresize(640,480)
SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
AudioDub (video,audio)
is completely equivalent to
video = mpeg2source("C:\PAL\PAL.d2v")
last = video.converttoyuy2()
last = last.convertfps(60000,1001)
last = last.lanczosresize(640,480)
last = last.SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
last = video.AudioDub (audio)
return last
or if it helps you can think of it this way:
video = mpeg2source("C:\PAL\PAL.d2v")
last = converttoyuy2(video)
last = convertfps(last,60000,1001)
last = lanczosresize(last,640,480)
last = SelectEven (last)
audio = WAVSource("C:\PAL\PAL.wav")
last = AudioDub (video,audio)
return last
This is because last is a special (normally unnamed) variable that gets assigned to anything otherwise unassigned, and used anytime no clip is explicitly specified. This should make clearer why everything bu tthe first assignment to video is skipped and why last is defined.
Also, simply using video.filter() will not reassign the result to video, it'll give it to last unless you assign it to something (eg, video=video.filter)
MuttLover
6th July 2006, 20:53
Thank-you! That clears up alot to me. I'd been tinkering with a script to combine 3 clips and add fadein & fadeout to each and had trouble getting the expected results.
Also, simply using video.filter() will not reassign the result to video, it'll give it to last unless you assign it to something (eg, video=video.filter)
I appreciate your response.
:thanks:
actionman133
6th July 2006, 21:55
Last is an implied variable. Basically, that means that if you don't specifically say a variable, it assumes you want it in Last.
Here's the above script, revised to show what AVISynth reads...
video = mpeg2source("C:\PAL\PAL.d2v")
last = video.converttoyuy2()
last = last.convertfps(60000,1001)
last = last.lanczosresize(640,480)
last = last.SelectEven ()
audio = WAVSource("C:\PAL\PAL.wav")
last = AudioDub (last,audio)
EDIT: someone beat me to it... teaches me not to write now and send two hours later, I guess...
foxyshadis
6th July 2006, 22:22
The highlighting was a nice touch though, I like that. =D I should use it for the wiki entry I'm planning to make on the topic.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.