############################################################################## # # Poor man's video standards conversion (NTSC to PAL and PAL to NTSC) # # This script converts one INTERLACED video format to another INTERLACED video # format with reasonable quality. # # NOTE: This script is NOT meant to convert telecined films (that is, films # in NTSC video format using 3:2 pulldown, or films in PAL video format # speeding the 24fps to 25fps). It is best for content like HOME MOVIES shot # with camcorders or live sporting events. # ############################################################################## # # This script is for use with AVISynth version 1.0 beta 3 or above. # # This script uses Gunnar Thalin's area-based deinterlace plugin for # VirtualDub, available at http://home.bip.net/gunnart/video/#deinterlacearea. # ############################################################################## # # USE: # # 1. Modify the "global" line below for your environment. # 2. Modify the last lines of the file for your desired conversion. # ############################################################################## # # For comments/suggestions email Xesdeeni2001 at the Yahoo mail server. # ############################################################################## global PluginPath = "PATH TO VDUB PLUGINS" # # VideoConvert() # # Function to convert one INTERLACED video format to another INTERLACED video # format. # # The function works by first converting the input video from interlaced to # progressive using an adaptive deinterlacer. Then the progressive frame rate # is converted to a progressive frame rate that is the same as the output # field rate. Finally the progressive frames are converted back to interlace # for output. Scaling is also performed where appropriate. # function VideoConvert(clip clip, \ float OutputFrameRate, \ int OutputFrameWidth, \ int OutputFrameHeight) { LoadVirtualDubPlugin(PluginPath + "\DeinterlaceAreaBased.vdf", \ "AreaBasedDeinterlace", \ 1) # # Get input video parameters # InputFrameRate = clip.framerate InputFrameWidth = clip.width InputFrameHeight = clip.height InputFrameCount = clip.framecount InputFieldRate = InputFrameRate * 2 # # Get output video parameters # OutputFieldRate = OutputFrameRate * 2 OutputFrameCount = \ round(InputFrameCount * (OutputFrameRate / InputFrameRate)) # Input video is clip supplied v1 = clip # When the output frame count is greater than the input frame count, due to # a problem with AVISynth, the output video is truncated so that it only has # as many frames as the input video. Here we work around this issue by # adding enough black frames to ensure all the frames are available on the # output. v2 = OutputFrameCount > InputFrameCount ? \ v1 + v1.Blackness(OutputFrameCount - InputFrameCount) : \ v1 # The deinterlacer will be set to interpolate missing lines instead of # blending the fields, where motion is detected (I think this looks better). # But the deinterlacer can only use one of the fields for this. If we # leave this as-is, on video in motion, we'll only get one position for # each pair of fields. Instead, we want one position for every field. # To do this, we'll use the deinterlacer twice on the same pair of fields # and interleave the results below. But in order for the deinterlacer to # use different fields in each case, we need to effectively reverse the # field polarity for one of our streams. The way I decided to do this was # to add an extra line to the top of the image, moving each line down. # The total number of lines must stay even, so I also add a line to the # bottom. v3 = v2 v4 = v2.AddBorders(0,7,0,9) # Each of our two streams is deinterlaced here. Because the deinterlacer # is a VirtualDub plugin, it requires RGB data. v5 = v3.ConvertToRGB().AreaBasedDeinterlace(0, 0, 27, 25) v6 = v4.ConvertToRGB().AreaBasedDeinterlace(0, 0, 27, 25) # Now we have to remove the extra two lines we added above. v7 = v5 v8 = v6.Crop(0,7,InputFrameWidth,InputFrameHeight) # Here we alternate frames between the two streams we created above in order # to produce a progressive stream with the same number of full frames as # we originally had fields. v9 = Interleave(v7,v8 ) # If we have more frames on the output than on the input, it is more # efficient to scale here. v10 = InputFrameRate <= OutputFrameRate ? \ v9.BicubicResize(OutputFrameWidth, OutputFrameHeight) : \ v9 # Using AVISynth's built-in filter, we either repeat or drop frames to # get the appropriate output frame rate. v11 = v10.ChangeFPS(OutputFieldRate) # If we have fewer frames on the output than on the input, it is more # efficient to scale here. v12 = InputFrameRate > OutputFrameRate ? \ v11.BicubicResize(OutputFrameWidth, OutputFrameHeight) : \ v11 # Now we convert our video back to interlace by separating the fields, # throwing out one from each progressive frame, and weaving the results # together. v13 = v12.SeparateFields().SelectEvery(4,0,3).Weave() # When the output frame count is less than the input frame count, due to # a problem with AVISynth, the output video is extended so that it has # as many frames as the input video. Here we work around this issue by # trimming the extra frames. v14 = OutputFrameCount < InputFrameCount ? \ v13.Trim(0, OutputFrameCount - 1) : \ v13 return(v14) } # # Convert INTERLACED NTSC video to INTERLACED PAL video # function NTSCToPAL(clip clip) { return(VideoConvert(clip, 25, 720, 576)) } # # Convert INTERLACED PAL video to INTERLACED NTSC video # function PALToNTSC(clip clip) { return(VideoConvert(clip, 29.97, 720, 486)) } ############################################################################## # # Uncomment ONE of the following lines and replace the file name with yours. # Change MPEGSOURCE to AVISOURCE/DIRECTSHOWSOURCE if not using MPEG #LoadPlugin("path to MPEG decoder") #video=NTSCToPAL(mpegsource("LiveTest.avi")) video=PALToNTSC(mpegsource("filename.d2v")) audio=WAVsource("filename.wav") audiodub(video,audio)