View Full Version : HD 1080i to DVD (all interlaced) - how?


florinandrei
30th June 2008, 06:24
I have an AVCHD file (.m2ts) that I want to convert to DVD. I use HCenc as the MPEG2 encoder, because it offers excellent quality.

The source is 1080i (interlaced, top field first), 29.97 frames / sec.
The destination is DVD, so it's 480i (interlaced), 29.97 frames / sec.

So it's an interlaced-to-interlaced conversion.

First off, I did a straight MPEG2 encoding, no resizing:

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
ConvertToYV12()

This worked fine. It produced an MPEG2 stream that was obviously too large (the encoder cannot resize) but looked OK. I opened it up in a player (VLC), hit Play, then Pause. Due to the jaggies on the moving objects, I deduced that the interlacing was preserved correctly. Cool. Now I needed to scale the image down to 720x480.

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
LanczosResize(720, 480)
ConvertToYV12()

That looks weird. It's like the moving objects consist of two "ghost" images on top of each other. Like a bad deinterlacer.

I tried a few options, like SeparateFields(), AssumeTFF(), to no avail.

So the problem is to scale down 1080i to 480i, at the same frame rate, while preserving interlacing. What is the "magic incantation" to do that?

By the way, at the end of the file, HCenc just hangs, "this program is not responding", so I have to kill it. Could be HCenc's fault, could be AviSynth's. Any ideas?

hanfrunz
30th June 2008, 08:08
Hello florinandrei,

please try something like this:
DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
SeparateFields()
LanczosResize(720, 240)
Weave()

hanfrunz

themostestultimategenius
30th June 2008, 08:10
You have to deinterlace before resizing.

DirectShowSource("File")
mcbob() #If you can spare the time. If not, use some other bobber.
Spline36Resize(720,480)
Weave()

Someone please correct the script if it's wrong.

Blue_MiSfit
30th June 2008, 08:41
You don't _have_ to bob before resizing - separating fields and resizing to 720x240 will work, but the bobbed version will probably look better :)

~MiSfit

Alex_ander
30th June 2008, 11:24
You have to deinterlace before resizing.

DirectShowSource("File")
mcbob() #If you can spare the time. If not, use some other bobber.
Spline36Resize(720,480)
Weave()

Someone please correct the script if it's wrong.

After bobbing the video has double frame rate and is frame based progressive.
To re-interlace it, one wants to use half of fields from it, like this:


LoadPlugin("path\LeakKernelDeint.dll")
DirectShowSource("path\video.mts")# better to use DGIndex project for mpegs
LeakKernelBob(order=1)# order=1 is for TFF input video
LanczosResize(720,480)
AssumeTFF()# the assumed order will force outputting TFF
SeparateFields()
SelectEvery(4,0,3)
Weave()


The previously suggested 'separate fields + resize' method (then SelectEven) would work good for progressive target video (in case the original video is not too sharp).

halsboss
30th June 2008, 12:01
http://forum.doom9.org/showthread.php?t=136109

florinandrei
1st July 2008, 01:14
You have to deinterlace before resizing.

I actually wanted to do tests first and then post a reply, but I'll post first, because it's an important issue to me:

Deinterlace before resizing sounds scary. I hope I don't have to do that. I definitely don't want to deinterlace, because, based on my previous experience with deinterlace/reinterlace filters with other applications, this always degrades the image.
My goal is to preserve the fluidity of the motion in pristine quality, and the way I understand the process now, that can't be done if I deinterlace/reinterlace.
Remember, both the source and the destination are interlaced: 1080i and 480i. So I will do my best to find a method to not deinterlace. After all, I came to AviSynth after being disappointed with some commercial software (http://www.camcorderinfo.com/bbs/t142395.html) which seems to deinterlace when there's no need to.

Please correct me if I'm wrong.

P.S.: I will do tests as soon as I can.

Blue_MiSfit
1st July 2008, 01:41
there's a difference between "normal" (half rate) deinterlacing, and bob deinterlacing.

Bobbing preserves all temporal information, so 1080i bobbed becomes 1080p60. Then, you can scale these 60fps down to 720x480, separate it into fields, throw away half the info, and re-interlace down to 480i

You can do all this without deinterlacing, but smart bobbing first will give better results - namely less aliasing etc due to spatial alignment I think.

~MiSfit

florinandrei
1st July 2008, 03:10
I used this script:

LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\LeakKernelDeint.dll")
DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
LeakKernelBob(order=1)
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()
ConvertToYV12()

I opened the result in VLC, the jaggies looked normal for a 480i. So far so good.

I generated the audio track, multiplexed, authored a very simple DVD image, burned it. It played just fine on the TV, although that test might be less relevant, since there are quite a few layers of processing on the PS3 and the HD screen which may mask issues with the DVD. But it looked good, no ghosting, no huge jaggies due to field order reversal (but I guess the PS3 would try and hide those), motion was fluid, etc.

So I guess this is it?

Any suggestions I could use to improve it? Remember, I am trying to convert 1080i TFF to 480i and keep everything interlaced, with fluid motion and crisp images.

henryho_hk
1st July 2008, 03:17
Have you tried the "InterlacedResize()" function in SimpleResize.dll ?

Edit(1): Unfortunately, is it said to be broken for YV12.

Edit(2): You probably need to apply some field shift correction for the separate-resize-combine method, as suggested in http://forum.doom9.org/showthread.php?p=594339#post594339

florinandrei
1st July 2008, 04:43
Have you tried the "InterlacedResize()" function in SimpleResize.dll ?

Edit(1): Unfortunately, is it said to be broken for YV12.

But it shouldn't matter, since ConvertToYV12() is applied after that, right?

henryho_hk
1st July 2008, 06:05
For best result, we need a motion-sensitive(compensated?) ConvertToYUY2 and ConvertToYV12. :devil:

BTW, nnedi+tmm+tdeint is a nice bobber too:

TFF Clips:
inp=src.nnedi(field=3)
emk=src.tmm(mode=1,order=1)
src.tdeint(mode=1,order=1,type=1,edeint=inp,emask=emk)

BFF Clips:
inp=src.nnedi(field=2)
emk=src.tmm(mode=1,order=0)
src.tdeint(mode=1,order=0,type=1,edeint=inp,emask=emk)

Blue_MiSfit
1st July 2008, 07:15
Yes! Please use TDeint+TMM+NNEDI!

LeakKernelBob is prety out of date :)

~MiSfit

florinandrei
1st July 2008, 09:23
Edit(2): You probably need to apply some field shift correction for the separate-resize-combine method, as suggested in http://forum.doom9.org/showthread.php?p=594339#post594339

So how about this:

Global NewHeight=480
Global NewWidth=720

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")

AssumeTFF()
SeparateFields()

Shift=(Height()/Float(NewHeight/2)-1.0)*0.25

Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()

ConvertToYV12(Interlaced=True)

Visually, it looks better. Those tiny but strange ripples on top of rising/falling oblique objects are gone.
The minimum bitrate and the average bitrate on the encoder have decreased. The encoder has an easier job to do. Not sure if this is a good sign or bad. I don't care about final file size, there's plenty of room left over on the DVD.

It's still a bit blurry. But perhaps this is not objectively true, perhaps I'm unconsciously comparing it with the HD master. Also, the PS3 is doing a lot of processing to convert the 480i to 1080p for the display - I know it's doing a lot of things because the upsampled standard-def (at least the commercial progressive material) looks unnaturally good in most cases. So that might interfere. These things are best verified on true 480i displays and players.

Tomorrow, or when I have time, I'll have to start drawing diagrams and verify whether those formulas that I copy/pasted in the new script are geometrically correct. Of course, the fact that I don't know squat about AviSynth doesn't help - I'm learning it as I go, and it kind of keeps me back. :mad: Only now I'm starting to realize the vast possibilities opened by AviSynth's scripting language.

2Bdecided
1st July 2008, 09:56
Yes! Please use TDeint+TMM+NNEDI!

LeakKernelBob is prety out of date :)As I always say at this point in the discussion: it really doesn't matter! You're throwing half the resolution away, and you have an interlaced output. Dumb bob is more than good enough - unless you have test signals, or similar high frequency gratings in your actual content, and you process the 480i output in such a way as to preserve these features - in that case only, you might notice softening, but it's pretty mild.

Cheers,
David.

2Bdecided
1st July 2008, 09:59
It's still a bit blurry. But perhaps this is not objectively true, perhaps I'm unconsciously comparing it with the HD master. Also, the PS3 is doing a lot of processing to convert the 480i to 1080p for the display - I know it's doing a lot of things because the upsampled standard-def (at least the commercial progressive material) looks unnaturally good in most cases.If the commercial content is 480p30 or 480p24 (typically wrapped in 60i), then it can be upconverted much more easily and crisply than 480i60. If you use 480p30 yourself (and maybe sharpen it a little, accepting the possibility of inter-line twittering on interlaced displays), it'll look just as crisp - but you'll lose the smooth motion of 480i60.

Cheers,
David.

henryho_hk
1st July 2008, 18:18
Agreed. Life is much more easy if it is an ITVC material. ^_^ florinandrei, perhaps you can host a few seconds of your clip somewhere and so we can try working on it too.

Edit: Just notice the "DirectShowSource()". Have you tried dgavcdecode at http://neuron2.net/dgavcdec/dgavcdec.html?

Blue_MiSfit
1st July 2008, 23:37
As I always say at this point in the discussion: it really doesn't matter! You're throwing half the resolution away, and you have an interlaced output. Dumb bob is more than good enough - unless you have test signals, or similar high frequency gratings in your actual content, and you process the 480i output in such a way as to preserve these features - in that case only, you might notice softening, but it's pretty mild.

Cheers,
David.


Sure, but NNEDI with TDeint and TMM is pretty damn fast, so why not use it? ;)

Either way - whatever the OP is happy with...

florinandrei
2nd July 2008, 03:13
Either way - whatever the OP is happy with...

I guess it's fair to say the OP has no clue. :)

Between these two scripts:

LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\LeakKernelDeint.dll")
DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
LeakKernelBob(order=1)
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()
ConvertToYV12()

Global NewHeight=480
Global NewWidth=720

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")

AssumeTFF()
SeparateFields()

Shift=(Height()/Float(NewHeight/2)-1.0)*0.25

Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()

ConvertToYV12(Interlaced=True)

The second one is definitely fuzzy. Anybody has a clue why? It was supposed to be the "perfect" resizer for interlaced movies.

The first one looks crisp, but I wonder if the jaggies aren't too much. I don't think there's any way to really tell, other than playing it on an old-school DVD player on a standard-def CRT TV. Anything else would just interfere with its own algorithms.

Just notice the "DirectShowSource()". Have you tried dgavcdecode?

I was skeptical at first, because they say it's essentially libavcodec in a nice package, and libavcodec has problems reading the AVCHD files produced by the new-gen HD cameras. ffmpeg, ffplay and VLC all have serious issues playing these files.
But anyway, I tried it and it works. Visually, there's no difference from DirectShowSource(). It does get rid of the annoying seconds at the end when AviSynth seems to hang and HCenc is totally frozen - with dgavc the encoder just exits normally.

perhaps you can host a few seconds of your clip somewhere and so we can try working on it too

Generous offer! Thank you.
I'd rather not make the initial file public (I sent it to a couple people, but putting it on a forum is a different thing), but I made 3 short clips that everyone can poke at:

http://dl.getdropbox.com/u/29966/00000.MTS
http://dl.getdropbox.com/u/29966/00001.MTS
http://dl.getdropbox.com/u/29966/00002.MTS

There's some motion, and there's some horizontal and oblique edges moving vertically.

there's a difference between "normal" (half rate) deinterlacing, and bob deinterlacing.

Bobbing preserves all temporal information, so 1080i bobbed becomes 1080p60. Then, you can scale these 60fps down to 720x480, separate it into fields, throw away half the info, and re-interlace down to 480i

You can do all this without deinterlacing, but smart bobbing first will give better results - namely less aliasing etc due to spatial alignment I think.

That sounds great, but how do you translate that in actual AVS scripts? Can you relate what you just said to the two scripts I posted above?

Guest
2nd July 2008, 03:47
That sounds great, but how do you translate that in actual AVS scripts? Can you relate what you just said to the two scripts I posted above? It's exactly what you did in your first script!

I don't agree that your second is fuzzy. You are imagining it.

IanB
2nd July 2008, 07:23
@florinandrei,

Interlaced resizing is fast, but you pay a price for generating each new field based only on the original field. Any new pixels spacially between 2 original field lines will effectivly be a weighted average of only the pixels above and below in that field, i.e. a blur. Effectively all the pixels in the new fields are vertically blurred slightly.

Using the SmartBob/Resize/ReInterlace method, although slower, will give vastly superior results in static areas because each new field can be based on a full frame. In static areas there is no "spacially between 2 original field lines". Those new pixels are rendered from complete frame data. i.e. no blur in static areas.

Of course in motion areas any difference can be attributed to how good the SmartBob interpolates the missing pixels. If using linear interpolators like in KernelBob or DGBob there will be no difference to Interlaced Resizing. i.e. a blur again. If using Edge Directed and/or Motion Compensated interpolators then the results can be a significant step up from bog interlaced resizing.

And apart from everything else the eye has trouble seeing bluring of things in high motion, it attributes motion to the blur, instead of blur to the blur. So it is a little unfair to look at individual fields on a PC screen, you really should evaluate the results on an interlaced display device at normal speed.

Alex_ander
2nd July 2008, 10:28
LeakKernelBob is prety out of date :)


NNEDI is newer, but this doesn't mean it can replace the 'outdated' Kernel bobber for any type of image - it works differently. Theoretically, in case of an image being as sharp as HD pixel resolution provides, it simply can't work correctly. It throws away one of the fields at interpolation and this means it halves vertical sampling frequency for an image which demands twice higher value by discretization theorem (by Kotelnikov/Nyquist). To have an illustration to what could happen sometimes, imagine a radical case of image type: all even lines in a still HD frame are black and all odd ones are white. NNEDI would simply alternate black and white frames, while Kernel bobber would still work somehow since it uses data from both fields. Of course the problem doesn't appear with softer or upsampled images and NNEDI is good there.

2Bdecided
2nd July 2008, 10:36
Effectively all the pixels in the new fields are vertically blurred slightly.Yes, demonstrably true, but...

1. You will then resize vertically to less than half the original resolution (or a little more than half the original resolution for "PAL") - that's a fair amount of blur!

2. You will then throw away half the remaining lines in each field to interlace the signal - that's a fair amount of lost information.

3. You will then rely on the deinterlacing in the display, if any, to restore those missing lines - or view on a native interlaced display, which will display inter-line twitter on sharp vertical details unless they are blurred before interlacing! Either way, you will be very lucky to see any extra detail you recovered with a "smart" bob.


As for "why not use X smart bobber - it's still fast?" – fast, yes, but everyone one I've seen (that counts as "fast") is prone to artefacts on something - sometimes quite nasty artefacts. The artefacts can be far more visible on the downconversion than any slight softness due to bobbing.

Of course mcbob to tgmc will do a better job and are almost always artefact free - but with these the slow down is considerable.

Cheers,
David.

2Bdecided
2nd July 2008, 11:05
To have an illustration to what could happen sometimes, imagine a radical case of image type: all even lines in a still HD frame are black and all odd ones are white. NNEDI would simply alternate black and white frames, while Kernel bobber would still work somehow since it uses data from both fields.Your point is well made - NNEDI "needs" to be used with something that can weave both fields as-is when necesary.

However your extreme example is too extreme. In an interlaced system, that image is ambiguous - the original image (before interlacing) could equally well be one frame black, then one frame white - or it could be two identical frames with alternate black/white lines. There is no way of knowing which, other than assuming.

All "smart" deinterlacing is based on assumptions - basically that the content changes little field by field - the camera is still pointing at roughly the same scene. If every field was completely independent, then a dumb bob would be the best you could do.

There are interesting graphs on pages 23 and 24 of this...
http://www.snellwilcox.com/community/knowledge_center/engineering_guides/edecod.pdf
...and I don't claim to fully understand them(!) but the stars represent typical content - mostly low detail and low movement (the centre of the stars) but a little fine detail and significant movement (the "arms" of the stars). If you had lots of fine detail and significant movement - almost random content, the frequency response wouldn't look like a star, but more like a square (up to the Nyquist limits for each dimension).

If you turn the stars into squares in the progressive plot, they don't overlap. If you turn the stars into in the interlaced plot, they do overlap. That's the ambiguous region. Your example is right in the middle of the overlap.

Cheers,
David.

2Bdecided
2nd July 2008, 12:03
I've attached two pictures.

The first one compares the output of bob (dumbest bobber available!) and mcbob (smartest bobber available).

I've stacked the output vertically, resized to 704x480, and added limitedsharpenfaster since the OP seems to want a sharp output (I don't think it's necessary). The script is:
avcsource("00000.dga")
assumetff()

lanczosresize(704,last.height)

a=bob()
b=mcbob()
stackvertical(a,b)

lanczosresize(last.width,480*2)

limitedsharpenfaster()

The output of frame 5 is in progressive.jpg, and the advantages of mcbob on the telegraph cables is just visible if you look carefully. Also, they are slightly more stable in the mcbobbed version than the dumb bobbed version.

However, that's not what the OP wants to do - the OP wants interlaced output.

If you interlace the image, and then do your best to watch it (either on an interlaced display, or via a great deinterlacer like mcbob) then it becomes almost impossible to see any difference. Really. The lines look the same, and their stability is the same.

This is shown in interlaced.jpg, where I took the video shown in progressive.jpg, interlaced it, and then ran it through mcbob. This is the code:
avisource("dga test.avi")

assumetff()
separatefields().SelectEvery(4,0,3).Weave()

converttoyv12(interlaced=true)

mcbob()

Now the advantage of the first mcbob is hidden - you might as well use bob when deinterlacing HD content for an SD interlaced output. If anything, the softer output from the original bob deinterlaces better than the sharper original output from mcbob.

The advantage of better bobbers in HD is not visible in the interlaced SD output for this content.

btw, either way, it's too sharp vertically for interlaced displays IMO - if anything, it needs slight softening in the vertical direction before interlacing, if you expect to watch it on a CRT.

Cheers,
David.

henryho_hk
2nd July 2008, 16:56
florinandrei, while you are bothering with the interlacing stuffs, you may want to consider another issue: aspect ratio.

Do you find your encoded NTSC 16:9 DVD looking a bit "wider/fatter" than your original 1920x1080 source?

As far as I know, if we take the pixel aspect ratio of NTSC 16:9 DVD as 40:33, your 1920x1080 1:1 material will scale to 704x480 [704 = 1920*(33/40)*(480/1080)]; after left and right pads of 8 pixels each, you have 720x480. On the contrary, if you resize to 720x480 directly, the resultant DVD will look a bit "wider/fatter" than your source.

If you don't want to have two thin black bars on the two sides, you may crop 12 pixels from (both) the top and bottom, making it 1920x1056, before resizing to 720x480.

2Bdecided
2nd July 2008, 17:40
I just go to 704 - it's a legal DVD resolution and saves confusion. It gets you the correct aspect ratio in software players and stand-alones (to within one pixel). No need to pad to 720.

http://forum.doom9.org/showthread.php?t=132378
http://forum.doom9.org/showthread.php?p=1100187#post1100187

However, most pros go to 720, and don't care about the slight error which they sometimes introduce, and sometimes don't.

Cheers,
David.

florinandrei
2nd July 2008, 19:02
OK, I'm starting to understand a few things.

Interlaced resizing is fast, but you pay a price for generating each new field based only on the original field. Any new pixels spacially between 2 original field lines will effectivly be a weighted average of only the pixels above and below in that field, i.e. a blur. Effectively all the pixels in the new fields are vertically blurred slightly.

Using the SmartBob/Resize/ReInterlace method, although slower, will give vastly superior results in static areas because each new field can be based on a full frame. In static areas there is no "spacially between 2 original field lines". Those new pixels are rendered from complete frame data. i.e. no blur in static areas.

In this message (http://forum.doom9.org/showpost.php?p=1154761&postcount=19), the interlaced resizing is the second script, right? If that's correct, what I don't understand is the usage of SeparateFields() - if the source is interlaced, what fields are there to separate? Aren't they already separated?
And bob is the first script? If that's the case your prediction appears correct, the second script seems to create output slightly blurred vertically, compared to the first one (at least on a computer and on the PS3 + flat panel).

Encoding speed has no importance to me. I prefer something that's very slow but very accurate. Encode once, watch forever - so better encode it right.

So, in that context, I guess you're saying: "use the first script but with the best bob you can find."

Of course in motion areas any difference can be attributed to how good the SmartBob interpolates the missing pixels. If using linear interpolators like in KernelBob or DGBob there will be no difference to Interlaced Resizing. i.e. a blur again. If using Edge Directed and/or Motion Compensated interpolators then the results can be a significant step up from bog interlaced resizing.

So, again, to obtain that result I just need to use the best bob available with something similar to my first script? E.g., mcbob() or something like that. I guess it's possible to simply remove LeakKernelBob() and just drop in something else? Something like this?

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
MCBob()
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()
ConvertToYV12()

Can that be called a very accurate interlaced resizer HD-to-DVD, for real-life video (not computer generated) with no scene changes?

So it is a little unfair to look at individual fields on a PC screen, you really should evaluate the results on an interlaced display device at normal speed.

I know. I guess I need to revive the old CRT and DVD player. That's a much bigger "project" than it seems. :)
OTOH, the DVD will be watched on progressive displays too, not just on old CRT. So I can't neglect either.

Of course mcbob to tgmc will do a better job and are almost always artefact free - but with these the slow down is considerable.

Not a problem. Accuracy comes first.

All "smart" deinterlacing is based on assumptions - basically that the content changes little field by field - the camera is still pointing at roughly the same scene.

That seems to be the case with the material I'm scaling. The source is an HD camera and there are no scene changes (a scene change is always the beginning of a new file).

added limitedsharpenfaster since the OP seems to want a sharp output

My fault, I should have phrased it better. I guess what I'm after is "accuracy". If the original is sharp, I want that sharpness preserved, as much as the scale-down allows. But the result should not be subjectively "sharper" than the original.
What I want is a reduced-size copy that looks, statically and dynamically, as close to the original as possible, aside from the smaller resolution. The master is interlaced HD video captured with a camera (not computer-generated) and has no scene changes. The result will be watched on a variety of screens, from plain old CRT to new smart upscalers + progressive HD panels.

I am aware that there might be conflicting requirements hidden here (such as accurate statically and dynamically). If that's true, that's one of the things I'm hoping to learn from this discussion.

florinandrei
2nd July 2008, 19:11
To put "accuracy" in perspective: I'm shooting with a consumer-level camera, but it's tweaked to be as neutral as possible. It has a Cinema mode which gives a somewhat flatter, non-aggressive gamma curve (unlike the "torch mode" on most cheap cameras) and I also changed settings such as saturation, brightness, etc. to make the result as neutral as possible. If I need brighter colors or bigger contrast, that can be taken care of in post - and now I see AviSynth could be used for that (but that's not the subject of this discussion).

I guess I should really use a "prosumer" camera, but those are 5 times more expensive. Can't do that now.

So I don't need something that looks flashy or "sharp" to the average user. I need something that is close to the original.

Blue_MiSfit
2nd July 2008, 19:20
I think you're taking a very good approach to this project. Kudos for sticking it out and trying to understand what's really happening, instead of throwing in the towel, copying and pasting a script, and being done with it. For reference, here's a little explanation of your script:


DirectShowSource("E:\video\birthday\STREAM\00000.MTS")

#At this point, your video is untouched true 1080i

MCBob()

#Now, we've bobbed 1080i to 1920x1080 @ 59.94fps.
#99.9% of your processing time will be spent here.

LanczosResize(720,480)

#Now we're down to 720x480 @ 59.94fps

AssumeTFF()
SeparateFields()

#Now we've pulled the progressive frames apart into 720x240 fields.
#It's technically at 119.89fps, but that doesnt matter ATM

SelectEvery(4,0,3)

#Now we've decimated away half the information like this:
#Input: A B C D
#Output: A C

#So, we're back to 59.94fps, still 720x240

Weave()

#Now we actually interlace the fields to produce interlaced frames.
#So, we're at 720x480 @ 29.97i fps

ConvertToYV12()

#And finally we convert the colorspace from something else to YV12
#(odd, because AVCHD should be YV12 - must be a decoder error).

#Actually, ConvertToYV12(interlaced=true) would be better


I hope that helps your understanding. As you guessed, any bobber - TDeint(mode=1), bob(), yadif(mode=1) etc etc could be dropped in here with equivalent results, but varying quality.

~MiSfit

mikeytown2
2nd July 2008, 20:06
Building off of Blue_MiSfit's script

DirectShowSource("E:\video\birthday\STREAM\00000.MTS")
#At this point, your video is untouched true 1080i

MCBob()
#Now, we've bobbed 1080i to 1920x1080 @ 59.94fps (1080P).
#99.9% of your processing time will be spent here.

ZoomBox(704,480,"LanczosResize", SourceDAR=16.0/9.0, TargetDAR=16.0/9.0, align=-5)
#Now we're down to 704x480 @ 59.94fps
#Resizer set for a source and target DAR of 16/9.
#Set Align=5 to get rid of black bars and crop instead of adding borders

AssumeTFF()
SeparateFields()
#Now we've pulled the progressive frames apart into 704x240 fields.
#It's technically at 119.89fps, but that doesnt matter ATM

#ConvertToYV12()
#Uncomment this to change colorspace. It's a good idea to change color space while it's still progressive video.

SelectEvery(4,0,3)
#Now we've decimated away half the information like this:
#Input: A B C D
#Output: A C

#So, we're back to 59.94fps, still 704x240

Weave()
#Now we actually interlace the fields to produce interlaced frames.
#So, we're at 704x480 @ 29.97i fps


ZoomBox Thread (http://forum.doom9.org/showthread.php?p=1111789#post1111789)
MCBob takes YV12() so your video is already YV12

Edit: Changed 720 to 704 after reading about DVD players from the links that 2Bdecided gave above (post 27).

IanB
3rd July 2008, 00:19
It seems a lot of the evaluation is being done here looking at static images. As this material is originally interlaced and motion fluidity is important it is vital to view the results in motion at normal speed, preferably on all the target displays. Having really great individual static bobbed frames that vertically twitter like crazy when viewed is about the worst result I could imagine. Examine carefully all thin vertical, horizontal and diagonal lines and sharp high contrast edges.


And one last point, if a ConvertToYV12() is required, where should it go.

I would recommend straight after the Bob and before the Resize. There is a whole raft of discussion about chroma positioning with interlaced 4:2:0 material. Summary is the chroma is positioned the same with both interlaced and progressive, but with interlaced, alternate lines are temporally distinct. This means for a static scene there is no difference between progressive and interlaced chroma. See these threads for the gorey details, AutoYUY2() updated and Adaptive chroma upsampling

2Bdecided
3rd July 2008, 19:32
Not a problem. Accuracy comes first.Going from 20fps to 1fps processing speed for no visible improvement isn't really searching after accuracy - it's OCD.

Cheers,
David.

Blue_MiSfit
3rd July 2008, 21:24
True :)

But the golden rule here is - whatever makes the user happy!

If that means encoding Blu-ray using Apple's MPEG-4 SP encoder at 512kbit, so be it! :D

~MiSfit

henryho_hk
4th July 2008, 04:39
Assuming that Bob() is good enough for 1080i to 480i downsizing, what about this?


AVCSource(dga="mts00000.dga")
#1920x1080i @29.97fps YV12

AutoYUY2()
#1920x1080i @29.97fps YUY2

Bob(0, 1, 480) # .... or Bob(0, 0.5, 480) ?
#1920x480p @59.94fps YUY2; shift correction automatically performed for the vertical resize

AssumeTFF()
#Dunno if the field order is preserved, so play safe

Separatefields().SelectEvery(4,0,3).Weave()
#1920x480i @29.97fps YUY2

ConvertToYV12(interlaced=true)
#1920x480i @29.97fps YV12; will it destroy the AutoYUY2() effects?

BicubicResize(704, 480, 0, 0.5)
#704x480i @29.97fps YV12

2Bdecided
4th July 2008, 11:44
But the golden rule here is - whatever makes the user happy!No, not when the user doesn't know what they want! ;) Seriously though, I think florinandrei wants to learn - that sometimes includes learning that what you originally thought you wanted to do isn't really what you want to do at all!


I'm still thinking about this statement...
I guess what I'm after is "accuracy". If the original is sharp, I want that sharpness preserved, as much as the scale-down allows. But the result should not be subjectively "sharper" than the original.
What I want is a reduced-size copy that looks, statically and dynamically, as close to the original as possible, aside from the smaller resolution.
IME I don't find HD>SD works like that at all. The sharpness of the HD original has little bearing on the sharpness of the SD output (unless it's badly out of focus). For a given processing chain, either both pin sharp and barely sharp HD will give sharp SD, or both pin sharp and barely sharp HD will give barely sharp SD.

If you do a bicubic resize and leave it at that, it'll all look a bit soft.
If you do a lanczos resize and run limitedsharpenfaster, it'll all look very sharp (too sharp?).
Neither will always "keep the perceived sharpness of the original, but on a smaller scale" - resizing doesn't work like that. You have to use the appropriate tools to get the sharpness you want, which is partly independent of the source. If you want it to look like the source, you'll have to throw in the processes that "recreate" that look at the new resolution, because it won't happen by magic.

I think I'm explaining this really badly, but I hope it make sense to someone.


Anyway, at least having a 60i input and 60i output will keep the motion looking the same - that part at least is "easy".

The problem is it contradicts the sharpness goal somewhat: whenever I see really sharp SD, it's progressive (25p in the UK). Interlaced SD never seems to look quite as sharp.

Cheers,
David.

henryho_hk
5th July 2008, 18:03
I don't agree that your second is fuzzy. You are imagining it.

Perhaps he is not. The wires in frame 5 got "broken" by the 2nd script. They are okay with shift=0 or with Bob's resize. Perhaps the shift calculation formula is wrong.

Guest
5th July 2008, 18:37
broken != fuzzy

henryho_hk
6th July 2008, 01:43
Sorry that my english is not good. Perhaps, when the shift adjustment is wrong, the two fields are misplaced. Hence, it makes the wire looking "broken" on computer monitor and the video looking "fuzzy" on CRT TV.

MVBob -> Separatefields -> Weave:

http://img380.imageshack.us/img380/162/00000f5mvbobwt9.jpg

Bob(0, 0.5, 480) -> Separatefields -> Weave:

http://img368.imageshack.us/img368/9969/00000f5bob05da8.jpg

Separatefields -> Spline36Resize (with shift adjustment) -> Weave:

http://img133.imageshack.us/img133/9143/00000f5separatespline36wo1.jpg

IanB
6th July 2008, 06:35
@henryho_hk,

Your last image looks like you had the 2 red statements reversed.Global NewHeight=480
Global NewWidth=720

AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25

Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()Please post the actual script you used :script:

henryho_hk
6th July 2008, 07:55
Your last image looks like you had the 2 red statements reversed.


Exactly.... I am so silly. :stupid: Thanks IanB. :thanks:

florinandrei
8th July 2008, 07:02
No, not when the user doesn't know what they want! ;) Seriously though, I think florinandrei wants to learn - that sometimes includes learning that what you originally thought you wanted to do isn't really what you want to do at all!

True.

I was thinking I should just do 1080i -> 480p at 30fps, since 480p/30fps, while not a DVD standard, is apparently supported by some (many?) DVD players. You know, just deinterlace and be done with it.
But then, these DVDs will be played on interlaced CRT displays, so it's probably better (?) to keep it interlaced.

One day I'll be able to shoot hi-def progressive and then a lot of problems will disappear. Interlacing is a really bad annoyance.
I was actually thinking to get a "prosumer" (semi-pro) camera, but then for the same price ($3k) next year one could shoot 3k progressive at 120fps in raw format :eek:

http://www.red.com/nab/scarlet

If it's not vaporware, then it beats the hell out of an XH A1 (http://www.usa.canon.com/consumer/controller?act=ModelInfoAct&fcategoryid=175&modelid=14061) at the same price.

Offtopic, sorry.

If you do a bicubic resize and leave it at that, it'll all look a bit soft.
If you do a lanczos resize and run limitedsharpenfaster, it'll all look very sharp (too sharp?).
Neither will always "keep the perceived sharpness of the original, but on a smaller scale" - resizing doesn't work like that. You have to use the appropriate tools to get the sharpness you want, which is partly independent of the source. If you want it to look like the source, you'll have to throw in the processes that "recreate" that look at the new resolution, because it won't happen by magic.

I see your point.
Yes, that is the goal - the perceived sharpness should remain the same (adjusted for resolution changes), preserving the original look. I guess I'll just have to try different things and see what works.

How about lanczos without limitedsharpenfaster?

Alex_ander
8th July 2008, 08:33
I was thinking I should just do 1080i -> 480p at 30fps, since 480p/30fps, while not a DVD standard, is apparently supported by some (many?) DVD players. You know, just deinterlace and be done with it.
But then, these DVDs will be played on interlaced CRT displays, so it's probably better (?) to keep it interlaced.


There's no incompatibility of progressive footage on DVD with interlaced display: the video is outputted by fields (fake interlaced if progressive) from any standard DVD player. The main reason for keeping video interlaced is preserving better motion reproduction. When you deinterlace without doubling frame rate (you can only double it for PC or for 720p TV playback) you lose half of motion phases and get some artifacts.

Blue_MiSfit
8th July 2008, 22:10
Right, but the whole reason interlacing was standardized in the first place was its ability to maintain motion fluidity while reducing bandwidth requirements. It still does this today, but with all the headaches etc that we all know and love :)

On that note, I'm impressed with the quality of a simple separatefields + spline resize, with offset correction. There's less aliasing on the power line than with MVBob!

I did some fun stuff last night - converting a 1080i VC1 adult title to 720p60 with a simple bob (with spline) and was very impressed! Of course, it wasn't as good as MCBob, but there were no motion artifacts, like there were with Tdeint (without using TMM anyway, which slows the whole process down a bit)

~MiSfit

henryho_hk
9th July 2008, 01:44
The aliasing on the power line also exists in the original 1080i material. Therefore, I wonder if separatefields + spline resize will look okay on interlaced TV.

florinandrei
11th July 2008, 06:22
ConvertToYV12()

#And finally we convert the colorspace from something else to YV12
#(odd, because AVCHD should be YV12 - must be a decoder error).

#Actually, ConvertToYV12(interlaced=true) would be better

Correct. I removed all references to ConvertToYV12() and the MPEG2 encoder (the AviSynth host running the script) keeps working just fine.
I know for a fact that HC Encoder complains if the input is not YV12 so that must be it, AVCHD is already YV12.

florinandrei
11th July 2008, 18:34
I did something like this:

SetMTMode(2,2)
AVCSource("00000.dga")
MCBob()
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()

It worked fine and the result looks crisp. But it's WAAAY to slow!
The first clip, 358 frames, took 2443 seconds to encode (0.15 fps). At this rate, a 1 hour video will take 200 hours to encode, or more than 8 days. I also tried MCBob-NNEDI but after some superficial testing that one appears to be even slower.
My system is a Core 2 Duo 5200 (one CPU, two cores).

Obviously, MCBob() is too slow for HD, unless it's used on very short clips.

I am willing to sacrifice time for quality, but the logistical issues with running a task for more than 8 days are pretty daunting since I can't dedicate a system to video processing (it's a machine I share with other people in the household). So it looks like I need to find a faster solution.

I noticed there are quite a few Bob functions, but I have zero experience with them. What I am looking for is something that is better that the most trivial Bobs, but not quite as slow as MCBob(). I am willing to wait up to 1 day for a 60 min video to encode, but that's I guess where I have to draw the line. So I have to speed up the process 8x. (*)
Motion compensated processing is a great idea, I understand the advantages, but it looks like MC on HD material with the current hardware is like encoding MPEG2 in 1997 - it just takes forever.

Can somebody point out some Bob functions that might fit the bill? (better quality than the most trivial ones, but faster than MCBob). As always, the goal is bobbing real 1080i footage (not computer generated, but filmed with a real camera) to shrink it to 480i.

Perhaps there are faster resize filters too, but my uneducated guess is that much more time is spent in MCBob() than in LanczosResize().
Also, I could speed up the MPEG2 encoder, which is currently running at max quality, but with these same settings, it produces 80 fps when encoding pure 480i footage, so I don't think it will make a measurable difference to tweak it in this context.
And a trivial Bob runs at 8 fps or so - I guess that's proof positive that MCBob() is the CPU hog.

(*) - I guess I could always buy faster CPUs, but even so I'm not sure whether MT.dll scales well enough with the number of cores, especially given the kind of filters I'm using. And a system that's 8x faster than my current one is going to be very expensive. I can't afford that.
OK, so I just realized that late next year, waiting for Moore's law, I might actually start using MCBob() on HD. But by that time I'm hoping to shoot all footage in 60 fps progressive for a not much bigger investment - bye bye interlaced video, you miserable evil thing. :p

P.S.: By the way, I am planning to keep doing experiments until I'm satisfied I have a procedure that converts 1080i to 480i at the best quality in a reasonable time with current hardware. When that happens, I will summarize my findings in a short HOWTO, either on this forum or on the AviSynth Wiki (if I can get permission to create content there). This looks like a topic that will become more important in the future, as the HD cameras become more popular while co-existing with legacy SD displays - so people will need ways to bridge the two kinds of formats while preserving a good image quality.
I will take a couple more weeks I guess. This is fun.

Didée
11th July 2008, 19:02
Try Yadif. It's not a "trivial" bob, and fast like hell.

Since you're shrinking vertically by more than 50%, the benefits of the more sophisticated bob filters are in the area of "dimishing returns", anyway.

Other bobbing alternatives there are plenty - Kernelbob, TDeint, YadifMod, MVBobMod, MVBob, TempGaussMC, whatnotelse ... TempGaussMC could be a choice for a "not-too-slow" mo-comp'ed bobbing filter, when used with fast settings ( (1,1,0,"Yadif"), essentially).

Blue_MiSfit
11th July 2008, 19:41
^ Listen to this guy, he knows what he's talking about ;)

Yadif is amazing, given its fantastic speed! I find its quality to be just below TDeint(mode=1), but with better stability, and a lower chance of artifacting. Another choice would be TDeint with TMM providing the motion mask, to reduce the chance of artifacts.

But yes, I think YADIF would be your optimal choice :)

~MiSfit

florinandrei
11th July 2008, 21:49
Thanks everyone, I will try the suggestions y'all offered.

Another choice would be TDeint with TMM providing the motion mask, to reduce the chance of artifacts.

Can you provide a script example please? Thanks.

:script:

Blue_MiSfit
11th July 2008, 22:20
A very simple example:


mm=tmm()
TDeint(mode=1, emtn=mm)


~MiSfit

PatchWorKs
13th July 2008, 10:20
For those who don't know, MediaCoder build 4130 (http://mediacoder.sourceforge.net/wiki/index.php?title=MediaCoder_Changelog#0.6.1.4130) now has the ability to correctly decode AVCHD (the format used by many HD camcorder)

Enjoy !

czerro
13th July 2008, 12:53
I'm curious, what is the incentive to Bob vs IVTC? I understand it makes it easier to convert back to 29.97fps with weave() thus making it easier to author, but there are tricks to get around that restriction (ie fake the framerate).

I have never authored DVD's but dealt with SVCD encoding back in the early days of portable image backup when DVD authoring at 2x for a 200 dollar drive (20 dollar 1-time DVD) was not really an efficient or cost-effective option... And many intelligent people, knowing how much 23.976 vs 29.97 fps can effect image quality on an 800 meg disc mpeg-2 *Hardware Player Compatible* stream, created programs to fake 29.97 flags on 23.976 sources. DVD hardware WILL play 23.976 source with 23.976 flags, but with a noticeable intermittent stutter. Also audio would often get out of sync on FastForward/Rewind/Pause/etc. DGPulldown was a genius program that worked by magic and dark voodoo (I'm pretty sure anyway) and would somehow by simply changing the flags in your 23.976 source (30 seconds of work) convince any hardware or software player that it was rendering a 29.97 fps stream. Intermittent stutter gone, and looked better than a "true" 29.97 fps "fake" (progressive as opposed to interlaced) stream.

I assume Avisynth's ChangeFPS(), AssumeFPS(), options perform some sort of similar function, although I've never had any reason to deal with them. Why is IVTC flag tampering not a superior way to maintain bits per frame (quality) over Bob/SelectEvery/Weave? I'd rather get away with compressing/rendering an HD source at 23.976 fps than 29.976 fps considering the framesize (1080i!)

Blue_MiSfit
13th July 2008, 22:40
I'm curious, what is the incentive to Bob vs IVTC?


The two are to be used for completely different sources.

In both cases, we want to take interlaced video, and deinterlace it without loosing info. However, the two types of sources (hard telecined video and pure interlaced videos) need to be handled differently.

Telecined video is essentially a progressive stream that has undergone a (sometimes nasty) process to make it "fit" inside a 29.97fps interlaced stream (assuming NTSC). So, to make 24p film content fit inside 60i ntsc, you cut the 24p into 48 fields per second, then duplicate some fields here and there, until you reach 60 fields per second. That's how telecine works.

If it's done properly, telecine is usually pretty simple to remove. If it's a common 3:2 pulldown, a simple TFM.TDecimate will remove the extra fields, and re-assemble the original 24p. There are more exotic methods for more exotic / broken sources, but this works most of the time.

Now, bob-deinterlacing should typically only be applied to TRULY interlaced video. i.e. when you do SeparateFields, and step through, each field represents a distinct temporal location. This is opposed to telecined material (where you have some duplicated fields that can just look a tiny bit spatially different).

Bobbing will take each temporally distinct field, and interpolate it to a full frame, using any number of special methods to use detail from other fields to assist in the interpolation process.

So, bobbing returns 60p. Same-rate deinterlacing can be as simple as bobbing followed by SelectEven, or there can be a dedicated same-rate algortihm. Same-rate deinterlacing returns 30p

(note, that 30p=29.97fps progressive, 60p=59.94fps progressive, 24p=23.976fps progressive, 60i=29.97fps interlaced).

The two are distinct procedures that should not be confused. One cannot simply apply IVTC to a pure interlaced stream, and expect meaningful results.

~MiSfit

florinandrei
14th July 2008, 01:37
TempGaussMC could be a choice for a "not-too-slow" mo-comp'ed bobbing filter, when used with fast settings ( (1,1,0,"Yadif"), essentially).

I tried to call the filter like this: TempGaussMC(1,1,0,"Yadif") and it gave me an error.
I tried it like this: TempGaussMC(EdiMode="Yadif") and it's slower than MCBob().

What's the correct syntax for TempGaussMC() that makes it faster than MCBob() without losing too much quality?

Didée
14th July 2008, 12:16
I tried to call the filter like this: TempGaussMC(1,1,0,"Yadif") and it gave me an error.
I tried it like this: TempGaussMC(EdiMode="Yadif") and it's slower than MCBob().
Since you managed to use named parameter syntax in your 2nd line (EdiMode="Yadif"), I think you'll be able to figure how to use the same named syntax for the 1st line.

Testing with SD content, everything with default settings (i.e. empty parantheses: MCBob() / TempGaussMC_beta1() ), I found that TempGaussMC is 40% faster than MCBob. With really fast settings, it's running 4 times the speed of MCBob (though the results are not all that brilliant, then). Moreover, TempGaussMC has a lower memory usage than MCBob. In short, with SD I cannot replicate your findings.

Figuring the special needs of HD-1080 is the job of you guys. If you want me to figure those needs, no problem: feel free to provide me with the according hardware ... a beefy quadcore with plenty of RAM and a mighty GPU will do for now. :)
(Since ingenuity doesn't automagically reflect in $$$ or €€€, it's beyond my possibilites, sorry. Please excuse that I am poor.)


NB, you're really shooting the butterfly on a wheel. Going 1080i -> 480i means your going from 100% image area down to 16.6% image area, or the other way round: you're loosing 83.3% image area in the process. Still, you want to use golden nails to hammer some planks together? The vast majority of the intermediate improvement (at the 1080p stage) will be lost again when you've reached 480i. A plain and fast bob() does pretty good for that task ...

2Bdecided
14th July 2008, 15:09
I think he's just a masochist. At least two of us have told him bob() is good enough!

btw, for typical camcorder footage shot without a tripod (i.e. the camera is never really still, so fields never really match) yadiff becomes the same as bob(), doesn't it?

Cheers,
David.

florinandrei
15th July 2008, 07:16
OK, I get it. :)

I'm focused on Yadif() since it's fast enough - I get between 5 and 6 fps from it, which is good enough: this way it could make a DVD before I get back from work if I start it in the morning.
The better bobs are too slow.
Also, I can't distinguish visually between Yadif() and the slower bobs - not for this kind of processing anyway.

But now I have another issue. I just made a DVD-RW with 3 different algorithms - separatefields/shift/interleave, tdeint/mmc, and yadif - and tested it on the PS3 with an HD (progressive) screen.
Shift looks okay, more or less.
But the other two vibrate very badly when there's motion, as if the order of fields is mismatched, or something. The script is:

SetMTMode(2,2)
LoadCPlugin("C:\Program Files\AviSynth 2.5\plugins\yadif.dll")
DirectShowSource("00000.m2ts", audio=false)
Yadif(mode=1)
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()

The HCenc ini is:

*MAXBITRATE 9500
*PROFILE best
*AUTOGOP 15
*CQ_MAXBITRATE 5.000
*AQ 1
*DC_PREC 10
*INTERLACED
*TFF
*NOSCD
*MATRIX mpeg
*LUMGAIN 1
*PRIORITY normal
*WAIT 1

This is the file:

http://dl.getdropbox.com/u/29966/00000-yadif.m2v

I think I'll start by sprinkling AssumeTFF() in various places and watch the results. Maybe it's because I'm forcing TFF in HC.ini and it's not TFF? But AssumeTFF() in the .avs should take care of that. :confused:

It's kind of surprising to fail like this. :mad: IIRC, I tested it before and it was fine. But the scripts have changed quite a bit meanwhile.

Blue_MiSfit
15th July 2008, 07:22
What does this look like:


MPEG2Source(...)

AssumeTFF()
SeparateFields


Step through it frame by frame. Is the movement smooth or jittery? If it's jittery, try AssumeBFF.

Don't sprinkle randomly :) Determine the field order, set it, and forget it :)

~MiSfit

Didée
15th July 2008, 08:05
DirectShowSource does not hand over the source's actual field order to Avisynth. If Avisynth doesn't have a discrete filed order info, it defaults to BFF. Yadif picks up the field order provided by Avisynth. Since your source is TFF, that's where things go wrong.

Possibility #1:DirectShowSource("00000.m2ts", audio=false)
Yadif(order=1,mode=1)

Possibility #2: (mostly preferred) DirectShowSource("00000.m2ts", audio=false)
AssumeTFF()
Yadif(mode=1)


Determine the field order, set it, and forget it
The "forget it" part can be dangerous, in case your filterchain contains a filter that always resets field order to BFF, such as Bob(). ;)

florinandrei
15th July 2008, 08:17
I just came back from the living room after watching the new version when I saw the new replies. :)

Yes, I fixed it with Yadif(mode=1, order=1).
I'll try AssumeTFF() before Yadif, although I'm not sure what's the difference. Is it because AssumeTFF() is applied to everything afterwards, not just to Yadif()?

On the big progressive screen, the power lines hanging in the air are a bit jagged. This could be just the limit of the deinterlacer on the Playstation3, which is usually very good but I assume is not perfect.

I'll try it on the native interlaced CRT - that should be the "make it or break it" test.

Gavino
15th July 2008, 08:49
I fixed it with Yadif(mode=1, order=1).
I'll try AssumeTFF() before Yadif, although I'm not sure what's the difference. Is it because AssumeTFF() is applied to everything afterwards, not just to Yadif()?

The two have the same effect, but it's best to get into the habit of putting Assume[T/B]FF straight after DirectShowSource. Then the rest of the script has the right information no matter what you put in it (except for broken Bob() :)).

See it as part of setting up your source, rather than as part of deinterlacing.

Alex_ander
15th July 2008, 13:33
Yes, I fixed it with Yadif(mode=1, order=1).
I'll try AssumeTFF() before Yadif, although I'm not sure what's the difference. Is it because AssumeTFF() is applied to everything afterwards, not just to Yadif()?

AssumeTFF() before Yadif will be ignored (unless you use order=-1), since it is taken from declared 'order' parameter (in case you use wrong 'order' value, you'll at best get field order reversed on output). After Yadif you get progressive video for which it doesn't matter. It is only important to define field order before SeparateFields(), otherwise AviSynth default BFF will be used at separation thus inverting field order (from expected) for interlaced output.

Gavino
15th July 2008, 15:55
AssumeTFF() before Yadif will be ignored (unless you use order=-1)
... which is the default.
It is only important to define field order before SeparateFields() ...
This seems to contradict what you've just said, as deinterlacing filters (like Yadif) will also generally use the assumed field order by default.

So the cleanest way is always to set it after a source filter that doesn't get it right, like DirectShowSource.

Alex_ander
15th July 2008, 19:18
... which is the default.

This seems to contradict what you've just said, as deinterlacing filters (like Yadif) will also generally use the assumed field order by default.


I don't see any contradiction here. 'Default' for order=-1 in Yadif means the field order assumed by AviSynth just before applying the filter and it can be set directly with AssumeTFF(). And this setting is used only for this operation and doesn't apply to the newly created progressive video. By default, for any field operation with it BFF setting will be used by AviSynth. For this reason it is important to set the wanted field order just before field separation.


So the cleanest way is always to set it after a source filter that doesn't get it right, like DirectShowSource.

This would work the same as setting field order for bob-deinterlacing, but only in case order=-1 for Yadif. Internally setting order=0 or 1 in Yadif or LeakKernelBob overrides any field order setting before them.

Gavino
15th July 2008, 20:41
Where I saw a contradiction was: you seemed to imply AssumeTFF has no effect except on SeparateFields, immediately after stating that it does have an effect on the behaviour of Yadif(order=-1). But that wasn't my main point.

And this setting [AssumeTFF] is used only for this operation and doesn't apply to the newly created progressive video. By default, for any field operation with it BFF setting will be used by AviSynth.

That's wrong. Try this:

DirectShowSource(...)
AssumeTFF()
Yadif(mode=1) # or any other mode
Info()

You will see that the TFF property is preserved.

Any filter that doesn't do this (except for something explicitly designed to reverse field dominance) is broken.
Unfortunately Bob() falls into this category. :(

But it's true that LeakKernelBob/Deint requires you to explicitly specify the order, so AssumeXFF doesn't do you any good with that filter anyway.

Alex_ander
15th July 2008, 21:44
That's wrong. Try this:

DirectShowSource(...)
AssumeTFF()
Yadif(mode=1) # or any other mode
Info()

You will see that the TFF property is preserved.


I've just tried this:
LoadPlugin("c:\Program Files\AviSynth 2.5\SpecialPlugins\LeakKernelDeint.dll")
DirectShowSource("E:\Transfers\Video\UHeep\01 - Lady In Black [ r0xb0x ].mpg")
AssumeTFF()
LeakKernelBob(order=1)
info()
and I clearly see BFF as field order. I did it before and that's why I expressed such conclusion. I'll test it for Yadif now to see the difference.

Alex_ander
15th July 2008, 21:51
And yes, it is different with Yadif: 'Assumed TFF' and it is taken from the previous to Yadif line. Any idea, why LeakKernelBob behaves differently?!

Guest
15th July 2008, 23:15
Any idea, why LeakKernelBob behaves differently?! Differently than what?

Gavino
15th July 2008, 23:40
And yes, it is different with Yadif: 'Assumed TFF' and it is taken from the previous to Yadif line. Any idea, why LeakKernelBob behaves differently?!
Looks to me as if LeakKernelBob inherits the bug exhibited by plain Bob. Just checked this and LeakKernelDeInt does it right.

Looking at the source, I see that both Bob and LeakKernelBob invoke AssumeFrameBased (http://avisynth.org/mediawiki/AssumeFrameBased) on their result. This in turn resets the clip properties to the default (BFF). I now find myself confused as to whether the bug is in Bob/LeakKernelBob, or in AssumeFrameBased itself, or perhaps there is no bug at all and that's how it's supposed to work. :( :confused:

What's clear is that Yadif behaves differently from Bob/LeakKernelBob in this respect.

IanB
16th July 2008, 00:21
The Bob()/AssumeFrameBased() parity reset issue is to be addressed in 2.6

:Edit: The current behaviour is to reset the parity state to default. This is not wrong, it is just the way it works.

The revised behaviour will be to copy the parity from frame 0 of the input clip, this is the behaviour that most of the external Bob filter authors have adopted, and what those who have discussed and argued about the issue believe is a more expected, practical and manageable behaviour.

The change is not transparent so scripts that rely on the current behaviour may need to be adjusted, this is why the change has been deferred until the next major revision.

Gavino
16th July 2008, 00:44
The Bob()/AssumeFrameBased() parity reset issue is to be addressed in 2.6
Ian, just to put our minds at rest, can you clarify how it should work and which filters are currently 'wrong'?

I thought I understood it but now I'm not so sure...

Alex_ander
16th July 2008, 05:23
BTW, TDeint in bob mode keeps the previous field order (like Yadif).

Alex_ander
16th July 2008, 10:39
The current behaviour is to reset the parity state to default. This is not wrong, it is just the way it works.


I've always thought it's OK (and even more natural) to have field order reset to default just after creating different type of video by bob, for the following reasons.
1.The fields which were top/bottom before bob no more belong to the frames for which field order was determined.
2.Most bob filters use additional parameters (=assumed field order) to output frames in correct order and thus ignore input field order used by AviSynth.
3.In case the video is further used as progressive, field order doesn't matter (for encoding, etc.), also in case the video is further re-interlaced, it is easier to force AssumeXFF(), than to first examine which order is assumed by a particular bob filter. This gives predictable field order for interlaced output. I've always done so and yesterday it was a discovery to me (since it never influenced on results) that some of the bob deintelacers I use bring input field order to their output, despite the fact they don't use it for their internal work (except when they are 'told' to do so).

2Bdecided
16th July 2008, 10:54
I totally disagree. The field order is a property of the video clip, and AVIsynth knows this.

Any bob which is just a bob is faulty by design if you have to tell it the field order, when it's already known within AVIsynth.

If you are going to use the resulting progressive video as-is, the nominal field order is irrelevant - so preserving or changing it is just fine.

If you are going to re-interlace the video, then you usually know if you want to change the field order - otherwise the natural and obvious thing to do is to maintain the original field order. Breaking this behaviour is a bug IMO, not a feature.

Cheers,
David.

Alex_ander
16th July 2008, 11:40
The field order is a property of the video clip, and AVIsynth knows this.
Field order is property of interlaced clip (apart from AviSynth) and keeps information where different parts of the frame should be displayed on time line. AviSynth keeps field order value for every clip but with progressive clip you are absolutely free to invert it for any further operation.


Any bob which is just a bob is faulty by design if you have to tell it the field order, when it's already known within AVIsynth.
Which one is not faulty then?
One of the older and respected ones LeakKernelBob() only takes it as internal parameter (default is 'none' by manual) and that's good: you'll never forget to determine actual field order for your imported clip, which not always coincides with what AviSynth gets to 'know'.

If you are going to re-interlace the video, then you usually know if you want to change the field order - otherwise the natural and obvious thing to do is to maintain the original field order. Breaking this behaviour is a bug IMO, not a feature.

To 'change field order' of progressive clip (the one it's labelled with)? No. At re-enterlacing you decide, which fields in which order you want to take from a double framerate progressive video, where frames go in correct order (due to correctly set bob filter). Then half of them you throw away and get interlaced video with field order you want, not the one inherited. If you Assume the wanted field order before field separation, you'll get it without taking on belief some 'original' order you want to change or leave as is.

IanB
16th July 2008, 11:42
@Alex_ander, 2Bdecided,

Your 2 posts are the 2 summation arguments from a very long and drawn out development thread. :search:

There is no right answer. It came down to what was a more expected, practical and manageable behaviour. For me the pivotal argument was, that it is not trivial to copy the parity across the Bob() filter script wise, but it is easy for the filter to internally copy the input parity to the output clip. And it is easy script wise to ignore this action and keep the default behaviour.

2Bdecided
16th July 2008, 12:17
IanB, that makes sense.

However, I have my own, less convincing argument...

AVIsource("clip.avi")
somebob
separatefields().selectevery(4,0,3).weave()
...should be a NOP, or as close to one as possible. (a) because you'd expect it to be, and (b) because a common use for this is to perform progressive only filtering on interlaced content after the bob. There's no sense forcing the script to be more complicated than it needs to be.

There is no right answerFor a developer, you're too humble. Or maybe not. ;)

Cheers,
David.

IanB
16th July 2008, 12:31
@2Bdecided,... that it is not trivial to copy the parity across the Bob() filter script wise ...As an exercise try to code up a script that behaves as your example does with the current Bob() rules.

Gavino
16th July 2008, 12:51
However, I have my own, less convincing argument...

Sounds pretty convincing to me. :)
There's no sense forcing the script to be more complicated than it needs to be.
Exactly. You're free to sprinkle AssumeXFF calls throughout your script just to be on the safe side (and given the current state, that's maybe not a bad idea), but in the absence of such calls, it seems logical to preserve the setting across filters.

Didée
16th July 2008, 12:56
@2Bdecided,As an exercise try to code up a script that behaves as your example does with the current Bob() rules.

I'm not quite sure if I get you ATM ... are you heading for the following almost-trivial wrapping code for Bob() ?
(BTW, yes the wrapper is missing the b,c parameters)

# wrapping bob(), this means bicubic interpolation of fields
# this function also passed the Fieldorder information to the output,
# unlike bob() which always resetts the fieldorder to BFF.
# The current field stays untouched.

Function DumbBob(clip Input, int "Height")
{
Input.Bob(0, 0.5, height = Height)
GetParity(Input) ? AssumeTFF() : AssumeBFF()
}

Leak
16th July 2008, 14:52
There is no right answer. It came down to what was a more expected, practical and manageable behaviour. For me the pivotal argument was, that it is not trivial to copy the parity across the Bob() filter script wise, but it is easy for the filter to internally copy the input parity to the output clip. And it is easy script wise to ignore this action and keep the default behaviour.
:D

But it's also perfectly possible to create a wrapper around LeakKernelBob that will feed it the order based on GetParity and use the correct AssumeXFF afterwards if you want that behaviour...

EDIT: Ugh, didn't notice there was another page where Didée already did (almost) exactly that... ^_^;;;

np: Boy Robot - Magic Toys For Girls And Boys (Rotten Cocktails)

2Bdecided
16th July 2008, 16:38
But that's a horrible bodge to fix an obvious bug. Much better to fix the bug itself.

...then if anyone still wants or needs to sprinkle their scripts with assumeXff, they can still do so.

...and those who don't need to think about field order, don't need to.

Cheers,
David.

florinandrei
20th July 2008, 07:17
Yadif(mode=1, order=1).

On the big progressive screen, the power lines hanging in the air are a bit jagged. This could be just the limit of the deinterlacer on the Playstation3, which is usually very good but I assume is not perfect.

I'll try it on the native interlaced CRT - that should be the "make it or break it" test.

I just did that. The power lines are still a bit jagged. Maybe I forgot how the interlaced display is supposed to look like. But I remember that interlaced video on interlaced display is not supposed to look quite that jagged.

Here's what: tomorrow I'll go back to the same place. I'll take the HD camera, and also the old DV camera, and shoot the same scene with both. Then I'll convert the HD footage to SD and compare the two on an interlaced display. IMO, there should be no difference between the two, other than that the sequence originally made on HD should look better (better camera, then it's scaled down).

I'll let y'all know what happens.

florinandrei
21st July 2008, 01:51
EDIT: There was no "shimmering". Bad choice of words. It was aliasing. I'll reply below and explain.

I went back to the place with the power lines, two cameras in hand: HD and SD (DV Super8). Both cameras shoot 16:9. The SD camera is pretty cheap and amateurish.
The SD video was encoded to DVD/MPEG2 with no processing (other than ConvertToYV12(interlaced=true)). The HD video was converted to DVD by 3 methods: Bob()/Lanczos(), separatefields/shift/interleave, and Yadif()/Lanczos().
I made a DVD with all 4 clips and compared them on a regular 4:3 SD (480i) TV and a plain old DVD player connected via Component.

Both the TV and the DVD player have a "16:9" mode; I guess the TV in 16:9 will just scan a smaller area on the screen so as to match the 16:9 aspect ratio, while the DVD player in the 16:9 mode will simply fill the whole screen with video when playing a 16:9 DVD (will not letterbox).
So I have to either set both the TV and the DVD player to 4:3, or both to 16:9. The result is roughly the same, but in 16:9 mode a 16:9 DVD will look sharper (letterboxing is wasting scan lines, while in 16:9 there's no letterboxing).

Anyway, the results with the TV and DVD player in 16:9 mode:
Bob() and Yadif() look very similar. I can't really tell, visually, if there's a big difference (and Bob doesn't encode much faster than Yadif either). Thin horizontal lines (power lines hanging in the air) are shimmering a little bit when the camera moves vertically. If they are not perfectly horizontal, they also look a bit jagged.
Shift/interleave has zero shimmering/jaggies. However, I have a hard time telling whether it's more "soft" vertically than Bob(). I know on the computer screen shift/interleave looks soft. On the interlaced 480i "16:9" TV I don't think I can actually see a difference. What I do see might be due to my imagination. This was very surprising.
The native SD video looks more similar to shift/interleave than to Bob(). It has essentially zero shimmering/jaggies - well, it does have a very tiny amount, which might be due to the 4:1:1 color "softness" of the master format (DV), which produces nasty color shimmering on hard edges.

In 4:3 mode all videos shimmer a bit at the power lines. This is expected, since it maps a 480i video on a "300i" screen, or something like that.

Compared to what I see on the computer screen, the verdict after watching on the 480i TV is very surprising. Shift/interleave is the most similar to a full native 480i processing chain. It doesn't shimmer, just like native 480i, and unlike Bob or Yadif. And it's not softer vertically than Bob or Yadif - if there is any softness, I'll have to do a lot more tests to reveal it, and the vast majority of viewers will not likely notice it.

I would love to hear your comments.
What I don't quite understand is how shift/interleave looks so soft (vertically) on the computer as to seem almost deinterlaced :-) but on the native 480i screen it looks similar to the native 480i video. I know there's less resolution on the TV, but I'm pretty sure that's not the whole story.

Here are the MPEG2 files:

Bob:
http://dl.getdropbox.com/u/29966/hd2dvd/hd-bob.m2v
Shift:
http://dl.getdropbox.com/u/29966/hd2dvd/hd-shift.m2v
Yadif:
http://dl.getdropbox.com/u/29966/hd2dvd/hd-yadif.m2v
Standard def:
http://dl.getdropbox.com/u/29966/hd2dvd/sd.m2v

This is a typical bob .avs for converting HD to DVD:

DirectShowSource("hd.m2ts", audio=false)
AssumeTFF()
# Choose one of these
#Bob()
#Yadif(mode=1)
LanczosResize(720,480)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()

This is the shift/interleave .avs:

Global NewHeight=480
Global NewWidth=720

DirectShowSource("hd.m2ts", audio=false)
AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()

This is the .ini for HCenc for HD (the one for native SD is very similar). It's very high bitrate encoding, to maximize quality, but not quite CBR.

*MAXBITRATE 9500
*ASPECT 16:9
*PROFILE best
*AUTOGOP 18
*CQ_MAXBITRATE 5.000
*AQ 4
*DC_PREC 10
*INTERLACED
*NOSCD
*MATRIX fox1
*LUMGAIN 2
*PRIORITY normal
*WAIT 1

This is how I encode:

HCenc.exe -ini HC-hd.ini -i hd-video-yadif.avs -o hd-yadif.m2v -log hd-yadif.log -frames all

henryho_hk
21st July 2008, 08:58
florinandrei, :goodpost:

Could you post a sample of the original DV avi somewhere? :D

NTSC DV 4:1:1 should be "sharp" vertically (coz 4:1:1 dun have vertical chroma sampling). I tend to believe the softness of sep-resize-int method is due to the resizing of alternate field lines as if they were adjacent to each other.

But then I dun understand why bob/resize/selectevery are shimmering on TV. :confused:

2Bdecided
21st July 2008, 13:22
A few comments...

Firstly, it's interesting - the "separate fields shift corrected" resize does surprisingly well, but it's not performing magic. What it's doing is blurring the image in the vertical dimension, while the bob resize is keeping it sharp.

It you _want_ to blur the image in the vertical dimension to get the same results from bob, this is pretty close...

Bob()
assumetff()
LanczosResize(704,480)
blur(0.0,1.0)
separatefields().SelectEvery(4,0,3).Weave()

It reduces the lanczos halos a little compared to no bluring, which you may or may not want. (I think they look quite ugly on the "separate fields shift corrected" version, being generated at a 240-line resolution rather than 480-line resolution).



Secondly, in my testing (not related to this thread), sources which cause a problem (e.g. shallow sharp lines, repeating fine patterns) benefit from softening in the vertical dimension before interlacing; other source do not (and look beter sharp). Broadcast cameras and format converters typically use a compromise, softening a little, but not enough to remove all aliasing. The place to tune and set this is in the progressive domain (in this case, the output of bob) - by doing the "separate fields shift corrected" trick, you can't alter what you're doing so easily.



Thirdly, I'm still not convinced by that "Shift" value calculation - it fails for the trivial case - i.e. if the new height is the same as the source height, it still tries to shift the image, which can't be right.

I think it should be...
avcsource("00000.dga")
assumetff()

NewWidth=704
NewHeight=480
amount_to_crop=((float(last.height)/float(NewHeight))*0.5)-0.5

separatefields()

Tf=SelectEven().lanczosresize(NewWidth,NewHeight/2,0,0,0,-amount_to_crop)
Bf=SelectOdd().lanczosresize(NewWidth,NewHeight/2,0,amount_to_crop,0,0)

Interleave(Tf, Bf)
Weave()

This gives a shift of 0.625, rather than 0.875, for the current case. The difference is nearly invisible, but I think it's the correct calculation in the general case. I'm sure someone will correct me if I'm wrong. I recall seeing some kind of correction in a thread, but can't find it - I figured out the above myself from first principles.

Cheers,
David.

Gavino
21st July 2008, 16:16
I'm still not convinced by that "Shift" value calculation - it fails for the trivial case - i.e. if the new height is the same as the source height, it still tries to shift the image, which can't be right.

I think it should be...
...
amount_to_crop=((float(last.height)/float(NewHeight))*0.5)-0.5
separatefields()
Tf=SelectEven().lanczosresize(NewWidth,NewHeight/2,0,0,0,-amount_to_crop)
Bf=SelectOdd().lanczosresize(NewWidth,NewHeight/2,0,amount_to_crop,0,0)
I think you're on the right track (the trivial case proves the previous calculation was wrong), but I think it should be

amount_to_shift=((float(last.height)/float(NewHeight))*0.5)-0.5
# this is (total) required relative shift of odd v even in field-based co-ordinates
separatefields()
Tf=SelectEven().lanczosresize(NewWidth,NewHeight/2)
Bf=SelectOdd().lanczosresize(NewWidth,NewHeight/2, 0, amount_to_shift, 0, height)

Two points to note here:
- since the top field is not displaced by SeperateFields or Weave, it seems to me all the shift should be given to the bottom field;
- your solution was scaling an image of the wrong height, so changing the scale factor as well as shifting.

Didée
21st July 2008, 16:37
No. IanB's initial code for interlaced resizing is correct. Period.

Look once more at it:
Global NewHeight=480
Global NewWidth=720

DirectShowSource("hd.m2ts", audio=false)
AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
Tf=SelectEven().LanczosResize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().LanczosResize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()


This code does NOT fail in the trivial case. When old_height == new_height, it calculates a shift of zero.

Note that in the "shift=..." line, "Height()" refers to the height of the field separated clip, which then is divided by the half of new_height. This division results to "1.0" in the trivial case. Proceed with 1.0 - 1.0 which equals zero. Zero times 0.25 is zero. Hence, the shift is zero for the trivial case.

BTW, it was me who "corrected" IanB in the shimmering bars thread, and I was wrong with that. I confused the shift correction needed for bobbing with the shift correction needed for interlaced resizing, which isn't the same. (For bobbing, you've to omit the "-1.0" from the shift correction term, subsequently resize to new_height/1, and omit the final weave().)

On this matter, IanB was correct from the very beginning.

Gavino
21st July 2008, 16:58
@Didée.

I took what 2bdecided said about the trivial case at face value, and didn't check back against the original, again working from first principles.

What I ended up with is basically the same as IanB's version, with the difference that I gave all the shift to the bottom fields instead of splitting it between top and bottom. Can you explain why this is wrong? (Note the distinction, as you pointed out, between this case and the usual bobbing one.)

EDIT: Is it something to do with the resizer being center-based rather than zero-based? I still don't quite see it though.

2Bdecided
21st July 2008, 17:39
Note that in the "shift=..." line, "Height()" refers to the height of the field separated clipMissed that, thank you.

Cheers,
David.

2Bdecided
21st July 2008, 18:05
My shift amount is equivalent to half a line in the final field, minus half a line in the original field (one line in the final frame, minus one line in the original frame).

Ian's shift amount is exactly half this.

Proof:
Ian's formula:
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
Before separate fields, height was double, hence this is equivalent to:
Shift = ((last.height/2)/(newheight/2) – 1.0) * 0.25
Shift = ((last.height)/(newheight) – 1.0) * 0.25
Shift = last.height/newheight*0.25 – 0.25

Which is exactly half of what I had:
amount_to_crop=((float(last.height)/float(NewHeight))*0.5)-0.5


I crop my value from the top of the bottom fields, and the bottom of the top fields. Of course this scales it - the distance from the first to last line in one field of the lower res picture is a shorter distance than from the first to last line in one field of the original higher res picture (think about it).

Ian crops his value from top of the bottom fields, and adds his value to the top of the top fields. This gives exactly the same inter-field offset as me at the top of the field, but an overall offset of 1/4 line per final field (1/2 line per final frame) relative to me at the top of the field. Ian is keeping 1/2 line per final field more picture data than me.


I don't state all this as fact. I state it as what I think at 6:03PM Monday evening - feel free to prove me wrong.

Cheers,
David.

IanB
21st July 2008, 23:40
EDIT: Is it something to do with the resizer being center-based rather than zero-based? I still don't quite see it though.resample_functions.cpp:234 // the following translates such that the image center remains fixed
double pos;
...
if (fir_filter_size == 1) // PointResize
pos = subrange_start;
else
pos = subrange_start + ((subrange_width - target_width) / (target_width*2));Yes the -ve shift of the top field is to undo the centre correction calculation inside the filter generator. And the +ve shift of the bottom field is the opposite. I discussed this with Wilbert in Cropping interlaced video = shimmering bars where I coined the term output uncrop.

One thing to remember here is we are going from a 1080i source to a 480i display, a 2.25 times reduction in height, there is so much excess information here it really won't matter how you convert it, as long as you do it correctly. In the smart Bob case it is more like a 4.5 times reduction.

Using dumb Bob followed by SeparateFields() is a way of cheating the Nyquist limit. Effectively you are doing a 540-(Bicubic)->480-(Point)->240 the Interlaced Resize method does 540-(Lanczos)->240 so the low pass filtering frequency is approximately double (point resizing does no anti-aliasing (low pass) filtering)

florinandrei
22nd July 2008, 18:06
OK, first off, I made a bad choice of words. There was no "shimmering" on the horizontal lines with those algorithms. What I was seeing was aliasing, stair-stepping. Sorry about the confusion, English is not my native language.

I did more tests. This time I put the DVD in the PS3 and watched on the 1080p screen. Everything looked pretty similar to the native 480i screen actually.
Bob and Yadif suffer from aliasing on the almost-horizontal lines.
Shift/interleave is rock solid, zero aliasing, and I had a discussion with a friend who was watching with me - I said I think it's slightly more blurry on the vertical than the other clips, while he said it was my imagination. After watching repeatedly, I didn't know what to think anymore. :rolleyes:
The native 480i video from the DV source actually had a little bit of aliasing on the big screen (unlike on the native 480i screen in 16:9 mode, where it was flawless), I guess due to the PS3's deinterlacing software.

I watched again everything on the interlaced CRT screen in 16:9 mode.
Bob and Yadif exhibit visible and annoying aliasing.
Shift/interleave has zero aliasing. Again, the same discussion: is it more blurry or not? I don't know if it's really blurry or it's just what I remember from the computer screen (on the computer it's clearly a bit blurry on the vertical). Even in 4:3 mode it still looked pretty good, maybe a hint of aliasing, barely noticeable if you know where to look.
The DV-source native 480i clip looks great in 16:9 mode (all 480 scan lines from the DVD are mapped onto 480 scan lines on the TV, since the scan area on the CRT is compressed vertically). There's some moderate aliasing in 4:3 mode (because there are 480 scan lines from the DVD mapped onto fewer than 400 lines on the TV).

I'm starting to realize just how bad the DV camera is. I wish I did the test with a better camera. Yes, it's just 480i, but even by that standard it's pretty lame.

Because this DVD will be watched on interlaced standard-def CRTs, most of them in 4:3 mode I guess, I am strongly inclined at this moment to just use shift/interleave and forget about Bob, Yadif and all that stuff. Unless somebody comes up with something new to try. :script:

Could you post a sample of the original DV avi somewhere? :D

I'll go one step above that.

Here's the DV file:
https://dl.getdropbox.com/u/29966/hd2dvd/sd.avi

And here's the AVCHD file:
https://dl.getdropbox.com/u/29966/hd2dvd/hd.m2ts

Now y'all have all the master files, all the results, and the scripts I used to do the processing.

Funny how the HD file is about half the size of the standard-def file, yet it has a lot more information. :) The technology really moves forward I guess.

Firstly, it's interesting - the "separate fields shift corrected" resize does surprisingly well, but it's not performing magic. What it's doing is blurring the image in the vertical dimension, while the bob resize is keeping it sharp.

Almost too sharp. There's aliasing in the image after bob that was not there before. I mean, compared to the native full end-to-end 480i chain, which looks perfect, bob clearly does something to the image, either adds some info, or removes something, or changes it, or a combination of the above.

Is it possible that the bob procedure is technically equivalent to an artificial sharpening?

Finally, my eyes tell me that bob needs "anti-aliasing". Isn't that essentially blur/softening? Are there ways to remove alias without making the image too soft?
Of course, this is all interlaced, which makes it pretty difficult to do anything. This forum needs a new icon - "I hate interlacing".

It you _want_ to blur the image in the vertical dimension to get the same results from bob, this is pretty close...

Bob()
assumetff()
LanczosResize(704,480)
blur(0.0,1.0)
separatefields().SelectEvery(4,0,3).Weave()

I'll try that, but honestly bob looks great on the computer screen. It's very sharp. If I could keep that and remove the jaggies... :)

And I'd rather use the other algorithm, if the result is the same, since it's faster. Or do you mean to tweak the blur to get an intermediate result?

It reduces the lanczos halos a little compared to no bluring, which you may or may not want. (I think they look quite ugly on the "separate fields shift corrected" version, being generated at a 240-line resolution rather than 480-line resolution).

What halos?

Secondly, in my testing (not related to this thread), sources which cause a problem (e.g. shallow sharp lines, repeating fine patterns) benefit from softening in the vertical dimension before interlacing; other source do not (and look beter sharp). Broadcast cameras and format converters typically use a compromise, softening a little, but not enough to remove all aliasing. The place to tune and set this is in the progressive domain (in this case, the output of bob) - by doing the "separate fields shift corrected" trick, you can't alter what you're doing so easily.

So, you're saying "do bob with softening while in progressive".

One thing to remember here is we are going from a 1080i source to a 480i display, a 2.25 times reduction in height, there is so much excess information here it really won't matter how you convert it, as long as you do it correctly.

That's what I expected. Yet the differences are fairly visible between the various scripts.

Using dumb Bob followed by SeparateFields() is a way of cheating the Nyquist limit. Effectively you are doing a 540-(Bicubic)->480-(Point)->240 the IntResize method does 540-(Lanczos)->240 so the high pass filtering is approximately double.

OK, that was a bit more than I could parse in one gulp. Can somebody rephrase this please?

2Bdecided
22nd July 2008, 18:19
OK, that was a bit more than I could parse in one gulp. Can somebody rephrase this please?That bit is what you're saying by "bob is too sharp", and I'm saying by "some people filter vertically before interlacing".

1080i-bob-then-resize is giving you 480 sharp lines which are perfect for weaving back together, but almost "too" sharp for interlaced display, and far too sharp for just looking at 240 of them (aliasing - higher frequencies than can be accurately represented).

The separated fields resizing is only giving you about 240-320 lines of resolution in the 480 output lines, but that's probably enough for interlaced display.

The problem/trade off is that interlaced display isn't just 240 out of 480, nor is it just all 480 perfectly weaved back together - it's a mish mash of the two depending on what your eyes (or the deinterlacer, on a progressive display) make of it.


Halos are, for example, white parts around the edge of black objects - you can see them above and below the power lines.

Cheers,
David.

henryho_hk
23rd July 2008, 02:43
VCD used to be fairly good on CRT TV and they look terrible on computer CRT monitor. Now DVD looks bad on a 22" LCD monitor. Monitors are really engineered to reveal the bad side of images.

BTW, what if we use BiCublinResize (http://ziquash.chez-alice.fr/) or even BilinearResize for the vertical dimension after Bob()?

florinandrei
23rd July 2008, 05:49
BTW, what if we use BiCublinResize (http://ziquash.chez-alice.fr/) or even BilinearResize for the vertical dimension after Bob()?

I was kind of thinking along the same lines. Use a dumb resize instead of a smart one. But perhaps that would be equivalent (to some extent) to Lanczos and then blur?

I'll have to try this.

florinandrei
23rd July 2008, 08:24
I took the Yadif script and made some variations.

First off, I tried 3 different resizes: Bilinear, Lanczos, and Spline36.
Lanczos and Spline36 are very hard to distinguish. The Yadif/Lanczos script is exactly the one I posted above, and I commented it already (crisp but aliased).
Bilinear seems to be less crisp, aliasing is not quite so bad but still visible.

Then I did a Yadif/Lanczos, either plain, or followed by blur(0.0, x) where x = (0.25, 0.50, 0.75, 1.00)
Obviously, increasing the x makes the video more blurry and reduces aliasing. With 0.75 aliasing is almost completely gone and it's a bit blurry but not too bad. Even with x=1.0, there is still a very tiny amount of aliasing visible. It's not exactly the same like shift/interleave.

I guess I will have to compare shift/interleave with blur with x either 0.75 or 1.0.
But I can't do that right now, I think I just bricked my main computer with a BIOS update. :mad:

2Bdecided
23rd July 2008, 10:26
Even with x=1.0, there is still a very tiny amount of aliasing visible. It's not exactly the same like shift/interleave.I thought that too. If you're happy with shift/interleave, and don't mind the halos, then I'd just use it.

Most people watching your video aren't going to be looking at the technical quality anyway (unless the content is really boring!).

Cheers,
David.

henryho_hk
23rd July 2008, 17:37
(unless the content is really boring!)

You remind me of those Blue-ray titles. :devil:

Suddenly I have one question on the shift correction. What does a negative "src_top" value mean for the resize? Does it mean a duplication of top pixels?

And.......... I still think that it's not a good idea to re-size the separated fields progressively as if the horizontal lines are laying on each other.

smok3
23rd July 2008, 18:33
Right, but the whole reason interlacing was standardized in the first place was its ability to maintain motion fluidity while reducing bandwidth requirements.

it was actually about the flicker, basically there are two min frequencies;

a. freq1 - enough for motion
b. freq2 - enough to eliminate the flicker
c. freq2 > freq1

more motion was a bonus basically.

Blue_MiSfit
23rd July 2008, 23:54
Fair enough :)

~MiSfit

florinandrei
15th August 2008, 09:27
I guess I will have to compare shift/interleave with blur with x either 0.75 or 1.0.

I did the comparison.

Short story:
The best looking on the native 480i screen is SeparateFields/Shift/Resize/Interleave.

Long Story:
With the screen in 16:9 mode (the scan lines are squashed vertically, so the active screen area becomes 16:9) and the DVD player told to output to a 16:9-capable TV, the connection from DVD to TV is a component cable, there's no doubt, shift/interleave looks great. There is ZERO aliasing. There's no perceivable blur from the normal viewing distance. I can't find any issues. Oh, and it's pretty fast.
Yadif + Blur 0.75 still has a little bit of aliasing.
Yadif + Blur 1.00 is virtually identical to shift/interleave. I thought there might be some aliasing, but it could be my imagination.
With the screen and the DVD player in 4:3 mode, all 3 movies look the same: there's a little amount of aliasing and the vertical resolution is not that great.

So, if nobody comes up with a better idea, this is what I'm going to use to convert 1080i to 480i:


Global NewHeight=480
Global NewWidth=720

DirectShowSource("hd.m2ts", audio=false)
AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
Tf=SelectEven().Spline36Resize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().Spline36Resize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()


In my tests, I used Lanczos instead of Spline36, but I assume spline will look slightly better (supposedly less ringing). I will test it, of course.

Many thanks to everyone. I learned a lot from all of you. :thanks:

2Bdecided
15th August 2008, 10:02
It's funny, I was just thinking about this thread when watching the Olympics yesterday. Many (all?) of the feeds are HD, and I'm watching the BBC's SD coverage. At least some of it must be downconverted from HD.

It's very sharp, with lots of aliasing - too much, really. However, it suggests that whoever designed the downconverter had basically the opposite subjective opinion of you florinandrei, or else simply did the job badly.

Cheers,
David.

florinandrei
15th August 2008, 18:03
It's funny, I was just thinking about this thread when watching the Olympics yesterday. Many (all?) of the feeds are HD, and I'm watching the BBC's SD coverage. At least some of it must be downconverted from HD.

It's very sharp, with lots of aliasing - too much, really. However, it suggests that whoever designed the downconverter had basically the opposite subjective opinion of you florinandrei, or else simply did the job badly.

Or maybe they did the best out of a really nasty job. It was real time, wasn't it? It's difficult.

By the way, the sharp, aliased methods don't look that sharp on the native SD (480i) screen. The difference in sharpness between Yadif (without Blur) and shift/interleave is minimal, vanishing really. But the difference in aliasing is big and noticeable. I do like sharpness (e.g. I actually think my Canon HF100 HD camera is too "soft" :rolleyes:), but not at the expense of big nasty visible aliasing.
If you try to "fix" Yadif with Blur, then it looks very similar to shift/interleave, except it's slower.
On an HD screen (or computer monitor) it's a different story, but then again, the SD movie is for SD displays.

All my SD tests were done with a pretty good Sony Wega CRT screen. It was all the rage and pretty expensive in 2001. So I think what I did is relevant for most SD users.

halsboss
15th August 2008, 23:17
There seems to be a related thread which talks about deinterlacing as a part of resizing... http://forum.doom9.org/showthread.php?t=140218

florinandrei, over there (maybe I should have posted it here instead) after testing I settled on the same as you (separate-shift-resize-weave with Spline36)... I also ask after a 2-pass HC.ini using lossless :)

2Bdecided
18th August 2008, 10:41
Or maybe they did the best out of a really nasty job. It was real time, wasn't it? It's difficult.The Alchemist manages much harder tasks in real time ;)

Cheers,
David.

2Bdecided
18th August 2008, 15:25
I've had a look on various TVs (50Hz CRT, 100Hz CRT, plasma)...

By the way, the sharp, aliased methods don't look that sharp on the native SD (480i) screen. The difference in sharpness between Yadif (without Blur) and shift/interleave is minimal, vanishing really.The difference in sharpness looks significant to my eyes. I split screened it, and as objects move from the "sharp" side to the "blured" side it looks like someone added some softening gel to them. But...

But the difference in aliasing is big and noticeable.Agreed. The aliasing in the sharp version is really objectionable / distracting. It depends on the content, but at worst it's simply not acceptable.

If you try to "fix" Yadif with Blur, then it looks very similar to shift/interleave, except it's slower.It depends what you do. It's hard to get rid of all the aliasing, maintain sharpness, and avoid halos, but there are other compromises between very sharp and very blurred. (see below).

On an HD screen (or computer monitor) it's a different story, but then again, the SD movie is for SD displays.I was surprised how similar they were, considering. The SD CRT maintained the sharpest look (unless you try something stupidly slow like mcbob on the PC, which can also be sharp), but the aliasing was nasty on all of them.


If you're happy with what you've found, then use it - it save a lot of time and hassle!

If you have more time to waste, there are useful suggestions in this thread...
http://forum.doom9.org/showthread.php?t=139948&page=2
...which is about 1080p25 to 576i50 without flicker - but of course after deinterlacing, our 1080i50 becomes 1080p50 and you can use the same tricks.

*.mp4 guy's filter (note: optimised for 576p; maybe he can do a version for 480p too?)...

# add interlaced source here
# add whatever bob here
#then...

mt_convolution(horizontal=" 1 ", vertical=" 0.038210901657426959 -0.037550193209593907 \
-0.071321291957842009 -0.089513860956413741 -0.059487989097957106 0.028344726218269046 \
0.149710222693422800 0.255497189418900370 0.297427044507872330 0.255497189418900370 \
0.149710222693422800 0.028344726218269046 -0.059487989097957106 -0.089513860956413741 \
-0.071321291957842009 -0.037550193209593907 0.038210901657426959 ", u=2, v=2)
spline36resize(704,576)
assumetff()
separatefields().SelectEvery(4,0,3).Weave()

...this is really sharp and increases visibility of small details, keeps aliasing down, but is ringy


My alternative...

# add interlaced source here
# add whatever bob here
#then..

spline36resize(704,576)
limitedsharpenfaster().Sharpen(0.5,0.0).Blur(0.0,1.0).Sharpen(0.0,0.5)

assumetff()
separatefields().SelectEvery(4,0,3).Weave()

...this is less sharp than above, but less ringy, and doesn't change the visibility of details much

(you might need assumebff(), and you will need 480 in place of 576 for the height)


When I was playing around with this and putting the various versions onto DVD to compare, I realised the major problem is encoding the result well enough to do justice to the quality, whichever method you use. Obviously the softer methods are slightly easier to encode, but I couldn't get QuEnc to maintain the quality of the originals. :(


the SD movie is for SD displaysWell, for a few years yet I think SD DVD will remain the mainstream distribution format for the majority of people - I know lots of people with HD displays without any way of feeding HD to them. However, the compromises involved in converting HD to SD make me want to give anyone with a PC a WMV or Xvid or X264 1280x720p50 version instead! The problem then is that there are different compromises, not least the difficulty in playing that file back as smoothly on a PC as it would look on a TV.

Cheers,
David.

florinandrei
21st August 2008, 00:08
# add interlaced source here
# add whatever bob here
#then..

spline36resize(704,576)
limitedsharpenfaster().Sharpen(0.5,0.0).Blur(0.0,1.0).Sharpen(0.0,0.5)

assumetff()
separatefields().SelectEvery(4,0,3).Weave()



So, how did you came up with the sharpen/blur sequence above? What was the rationale? Or was it trial and error?

2Bdecided
21st August 2008, 10:34
I just threw in some numbers to try to match the perceived sharpness of mp4 guy's filter, while trying to avoid ringing and too much aliasing. Because of what mp4 guy has done, even a very sharp resize with no filtering looks far softer than his filtered version.

So, sorry, no rationale!


I was noticing on the BBC news last night how studio shots look quite sharp, with absolutely no aliasing and little ringing, while downconverted HD, and standard "inferior" SD, often does have aliasing. Whether the HD with aliasing looks sharper than the alias-free studio shots, I'm not sure. I'd love to know the various approaches the professionals take to this.

Cheers,
David.

florinandrei
22nd August 2008, 06:10
I just threw in some numbers to try to match the perceived sharpness of mp4 guy's filter, while trying to avoid ringing and too much aliasing. Because of what mp4 guy has done, even a very sharp resize with no filtering looks far softer than his filtered version.

I compared these scripts:

AssumeTFF()
SeparateFields()
Shift=(Height()/Float(NewHeight/2)-1.0)*0.25
Tf=SelectEven().Spline36Resize(NewWidth, NewHeight/2, 0, -Shift, Width(), Height())
Bf=SelectOdd().Spline36Resize(NewWidth, NewHeight/2, 0, Shift, Width(), Height())
Interleave(Tf, Bf)
Weave()

AssumeTFF()
Yadif(mode=1)
Spline36Resize(720,480)
LimitedSharpenFaster().Sharpen(0.5,0.0).Blur(0.0,1.0).Sharpen(0.0,0.5)
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()

On an HD screen, the first one looks very smooth. Maybe a bit blurry. No aliasing.
The second one looks apparently sharp, but it's pretty clear the sharpness is artificial. It's like one of those TV screens with sharpness turned way up to attract customers in the store. Also has a bit of aliasing.

On an SD screen, the second script looks good and appears sharper than the first, but it's hard to tell whether it actually provides more detail, not just the subjective impression of sharpness. I couldn't find any details that were actually not visible with the first script. The difference in terms of aliasing is small.

Something that I'd like to do at this point is to test eye fatigue. One problem with apparently sharp images is that they fool the eye on the short term, but long term produce fatigue. I became aware of this after calibrating my TV for the first time - it made a huge difference in the quality of image and comfort of viewing.
Unfortunately, this kind of test requires a lot of time, and that's something I don't have.

I'm still leaning towards the first script, based on everything I've seen so far.

At some point I'll start dumping all my HD home videos on DVD (1080i AVCHD, a.k.a. poor man's Blu-Ray) because right now they're on a hard-drive and it's filling up. At that moment I'll definitely have to make a decision, since that's when I need to also make the DVD 480i versions.

2Bdecided
22nd August 2008, 09:49
At some point I'll start dumping all my HD home videos on DVD (1080i AVCHD, a.k.a. poor man's Blu-Ray) because right now they're on a hard-drive and it's filling up. At that moment I'll definitely have to make a decision, since that's when I need to also make the DVD 480i versions.IME if the DVD versions are for other people, they'll probably be happy with whatever you give them. If they're for you, you'll never be happy, having seen the HD source.

If you want to keep your home videos long term, I think it's risky just keeping a single copy. For the raw footage, I currently keep the original HDV tapes, and the m2t files on a HDD. The costs of DV tape and HDDs are similar now - the tapes will last longer (the machine to play them may not!) but the HDD is more convenient. Data redundancy is good. I can do the same for edited footage, but haven't done yet.

I guess with an AVCHD source, HDD and DVD-R are a good choice - but choosing just one or the other is like saying "one day I'll dump all this footage".

If you have that much footage, IanB's method has the huge advantage of being the fastest. If HD>SD is trivial, then you only have to backup the HD versions IMO. If HD>SD is mcbob-like slow, you have to backup both to preserve the time/effort investment you made in converting (again, IMO!). YMMV.

Cheers,
David.
EDIT: P.S. - for the kind of difficult comparisons you're making (i.e. are there any more "real" details with method X or Y), it might be worth shooting or sourcing an HD test card. It might not be very representitive of real life footage though!

florinandrei
22nd August 2008, 10:29
Very good points.

The DVDs are for other people. I was just trying to do my best but yeah, they will probably think the DVDs are fine no matter what.

I am aware of the issues with single copy and long term archival. Currently, my old SD videos are 3 copies, on at least 2 different kinds of DVDs, stored on different continents. :) (one copy here, two other copies with my parents and my wife's parents in a different country)
HD is more difficult. I was planning to burn at least 2 copies, on 2 different kinds of DVDs, and store them in geographically dispersed locations. But the HDD suggestion sounds good. I'll have to think about that. The price per TB is going down fast.
IanB's method is definitely the fastest. I can afford to use a high quality resize without dragging it down too much.

One day I'm hoping to upgrade to something like Scarlet (http://www.red.com/) and then storage will be even more difficult. :mad: But by then BD will be more affordable, hopefully. Also the price per TB.

Gavino
22nd August 2008, 11:20
@florinandrei

As I think you are working with YV12 material, you should keep an eye on the other thread where we are discussing a correction to IanB's resizing method. Basically, the original method produces a slight error in the chroma for YV12.

See here and following.

halsboss
23rd August 2008, 16:36
Thanks, this post seems to finally say that the right thing to do for this method (given PAL HDTV 1080i->576i) is

SetMTmode(mode=2,threads=4) # mode=2 for temporal multi-threading (interleaved frames) ??????????
Global NewWidth=720 # or maybe 704 ? ... 704 could mean lesser area but hence leaving higher bitrate for that lesser area ?
Global NewHeight=576
SeparateFields()
Shift=(GetParity() ? -0.25 : 0.25) * (Height()/Float(NewHeight/2)-1.0)
E = SelectEven().Spline36resize(NewWidth, NewHeight/2, 0, Shift)
O = SelectOdd( ).Spline36resize(NewWidth, NewHeight/2, 0, -Shift)
Ec = SelectEven().Spline36Resize(NewWidth, NewHeight/2, 0, 2*Shift)
Oc = SelectOdd( ).Spline36Resize(NewWidth, NewHeight/2, 0, -2*shift)
Interleave(E, O)
IsYV12() ? MergeChroma(Interleave(Ec, Oc)) : Last
Weave()

Aassuming we use MT.

EDIT: can some knowledgeable person please confirm that SetMTmode won't muck this up in terms of interleave etc ?

*.mp4 guy
23rd August 2008, 17:35
low ringing (and low detail) lowpass for 1080i->480i.

mt_convolution(horizontal=" 255 ", \
vertical=" -0.00457430142084469586164799888191 -0.91092031121042564306650907803944 -2.7215434011820571965496188952936 -4.2381040109875854130339774799147 -2.7739456768086984932442890697262 4.556137386140445570028490752454 18.505136047840382914953022942635 36.000435907859456703965425655238 50.797650942298968076309880259519 56.609999970907811068675436793984 50.797650942298968076309880259519 36.000435907859456703965425655238 18.505136047840382914953022942635 4.556137386140445570028490752454 -2.7739456768086984932442890697262 -4.2381040109875854130339774799147 -2.7215434011820571965496188952936 -0.91092031121042564306650907803944 -0.00457430142084469586164799888191 ", u=3, v=3)

2Bdecided
23rd August 2008, 19:18
*.mp4 guy,

Could you do 1080i>576p please? If you have time.

Cheers,
David.

florinandrei
23rd August 2008, 23:29
low ringing (and low detail) lowpass for 1080i->480i.

Is that "black magic" :) explained somewhere? I'm looking at the numbers and I can't figure out exactly what's going on.
What makes it low ringing? What makes it low detail? What do I need to change to make it "high detail" or anything in between if I want to?
What does it do beyond a simple yadif().spline36resize().separatefields().selectevery().weave() ?

P.S.: I know what "convolution" means in general, and I'm familiar with this concept from audio processing (i.e. convolution filters to mimic the reverb of a cathedral), but in this particular case I have no idea what's happening.

halsboss
24th August 2008, 01:51
low ringing (and low detail) lowpass for 1080i->480i.

mt_convolution(horizontal=" 255 ", \
vertical=" -0.00457430142084469586164799888191 -0.91092031121042564306650907803944 -2.7215434011820571965496188952936 -4.2381040109875854130339774799147 -2.7739456768086984932442890697262 4.556137386140445570028490752454 18.505136047840382914953022942635 36.000435907859456703965425655238 50.797650942298968076309880259519 56.609999970907811068675436793984 50.797650942298968076309880259519 36.000435907859456703965425655238 18.505136047840382914953022942635 4.556137386140445570028490752454 -2.7739456768086984932442890697262 -4.2381040109875854130339774799147 -2.7215434011820571965496188952936 -0.91092031121042564306650907803944 -0.00457430142084469586164799888191 ", u=3, v=3)

Nice, if a little cryptic :) Any suggestions for 1080i->576i ?

IanB
24th August 2008, 10:19
@*.mp4 guy,

Yes, it might be nice if you share the maple script or whatever you are using to generate the coefficients to this 19 tap filter. And are you sure about your parameters, the provided filter seems to low pass at about 60 lines, I would expect it to be somewhere between 120 and 240 lines.

*.mp4 guy
25th August 2008, 04:33
It does lowpass between 120 and 240 lines, but because it is low ringing and has a low number of sample points (relatively speaking, you need more and more sample points the more frequencies you eliminate) it loses a lot of frequency amplitude all the way to around 60 lines. This filter is a simple chebyshev windowed sinc fir filter.


frequency response graphs:
The filter I posted (http://img135.imageshack.us/img135/4205/frequencyresponsecd2.png)
A bit more aggressive filter (http://img82.imageshack.us/img82/8654/frequencyresponse2gg6.png)
non windowed sinc, with 2x the sample points (http://img135.imageshack.us/img135/5830/frequencyresponse3ip5.png)

The line shows the aproximate location of the ideal cut off point, the boxes indicate manifestations of ringing.

mikeytown2
25th August 2008, 06:27
@*.mp4 guy
would you mind explaining what software package you used to create the numbers/graphs?

My guess is http://octave.sourceforge.net/
found this graph with GNU Octave Code: http://en.wikipedia.org/wiki/Image:Phase_Plots.svg

web front end of Octave http://hara.mimuw.edu.pl/weboctave/

*.mp4 guy
25th August 2008, 21:09
In this case I used winfirdesigner (http://www.elektronikschule.de/~krausg/DSP/Dsp_CD/DSP_and_FFT_and_Digital_Filter_Programs/WinFIRDesigner/) which is a simple freeware fir filter design program that supplies some nice graphing functionality. I've never heard of Octave, but it looks interesting.

florinandrei
30th August 2008, 05:20
I tested the convolution script posted by *.mp4 guy but it's very slow and it's very blurry. The vertical resolution is bad and the conversion speed is like 0.5 fps on a fast machine.

I tested the new corrected shift/interleave script:

Global NewHeight = 480
Global NewWidth = 720

DirectShowSource("hd.m2ts", audio=false)

# Pick one manually, DirectShow has no idea
AssumeTFF()
#AssumeBFF()

SeparateFields()

Shift = (GetParity() ? -0.25 : 0.25) * (Height()/Float(NewHeight/2)-1.0)

E = SelectEven() . Spline36Resize(NewWidth, NewHeight/2, 0, Shift)
O = SelectOdd() . Spline36Resize(NewWidth, NewHeight/2, 0, -Shift)
Echr = SelectEven() . Spline36Resize(NewWidth, NewHeight/2, 0, 2*Shift)
Ochr = SelectOdd() . Spline36Resize(NewWidth, NewHeight/2, 0, -2*shift)

Interleave(E, O)
IsYV12() ? MergeChroma(Interleave(Echr, Ochr)) : Last
Weave()


Compared with the initial version (that didn't process chroma separately), this one looks very similar. I didn't do an A/B comparison, but viewing them successively I can't tell any difference.
The corrected version is a bit slower (10.3 fps vs 12.7 fps) but that's OK. This new script supposedly deals with chroma correctly, so I think I'll just use it.

Are we out of ideas yet? :)