View Full Version : Useful function for checking TopFirst
trbarry
27th September 2002, 14:06
When is a clip "TopFirst"?
Interlaced video clips have 2 different fields in each frame and you are never quite sure which one was intended to be displayed first and which second when displaying interlaced or when deinterlacing. But some of my filters (GreedyHMA, TomsMoComp) make you specify that when invoking them.
So I just wrote a quickie Avisynth function that makes it easy to know if the clip is stored "TopFirst". The following function will do it fairly reliably:
later edit: see updated version on page 2 of this thread.
function CheckTopFirst(clip v1){
t0=v1.ComplementParity
t1=t0.separatefields
t2=compare(t1.trim(1,0),t1)
b1=v1.separatefields
b2=compare(b1.trim(1,0),b1)
return stackvertical(t2,b2)}
Run the function with something like:
v=AVISource("C:\whatever\bikes.avi")
CheckTopFirst(v)
Then preview a few frames. It will use Compare to evaluate the two possibilities and vertically stack the results. This shows 2 useful pieces of info. First the preview of either the top or bottom half of the screen will probably be jerky, so choose the other one.
But just as reliable is the "Avg Mean Abs Dev" value that is displayed for each. Choose either the top (TopFirst=1) or bottom (TopFirst=0) clip that has the LOWEST value for Avg Mean Abs Dev.
Picture attached. In this example the Avg Mean Abs Dev is 6.143 for the top and 7.549 for the bottom, so the clip is TopFirst.
- Tom
Boulder
27th September 2002, 16:12
Thanks Tom, this is greatly appreciated!
Wilbert
27th September 2002, 16:33
Less work:
clip=AviSource("C:\Temp\synchro_external.AVI")
clip.subtitle(String(clip.GetParity?"TopFirst":"BottomFirst"), font="MS UI Gothic")
wotef
27th September 2002, 17:27
both are cool, thanks - but wilbert where did getparity come from?
i see nothing on avisynth.org nor through a search here
trbarry
27th September 2002, 17:36
What does GetParity do? I thought Avisynth just assume a clip was bottom first unless you told it different.
- Tom
Wilbert
27th September 2002, 17:39
both are cool, thanks - but wilbert where did getparity come from? I see nothing on avisynth.org nor through a search here
It's not there yet. You can find it on the project page (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/avisynth2/avisynth/docs/syntax.html?), scroll down to clip-properties.
The documentation on www.avisynth.org is a little bit behind schedule :( It would be nice if more people can copy-paste stuff from the project page to www.avisynth.org.
Si
27th September 2002, 19:42
@Wilbert
GetParity is just Avisynths internal state flag - it always assumes a clip is bottom field first (It must have been so on Ben's capture set up :) )
Toms function is attempting to actually work it out :)
regards
Simon
wotef
28th September 2002, 13:38
yes, that's right!
would there be a way, then, for the avisource command to run tom's function automatically and set its internal state flag to whatever has the lowest avg mean dev? i.e. so that parity is set correctly first time without user intervention?
any filters that require parity input parameters could instead, as default behaviour, then just use whatever the internal state flag is set to
trbarry
28th September 2002, 15:39
would there be a way, then, for the avisource command to run tom's function automatically and set its internal state flag to whatever has the lowest avg mean dev? i.e. so that parity is set correctly first time without user intervention?
I've considered that for some time, and it wouldn't be hard to implement but for 2 issues:
1) It has some performance impact since it is doing a couple compares on every frame, so we wouldn't want to do it where not needed. This would suggest maybe an optional AutoSetParity filter.
2) Parity is kept by clip, not by frame. It is possible with some clips (or concatenated clips) that it changes in the middle. I'm not quite sure what the ramifications are here.
- Tom
niiyan
28th September 2002, 20:00
Thanks,Tom!
It's a very usuful function.
But,I have questions.
Originally posted by trbarry
But just as reliable is the "Avg Mean Abs Dev" value that is displayed for each. Choose either the top (TopFirst=1) or bottom (TopFirst=0) clip that has the LOWEST value for Avg Mean Abs Dev.
Picture attached. In this example the Avg Mean Abs Dev is 6.143 for the top and 7.549 for the bottom, so the clip is TopFirst.
You mean,if the value for the Avg Mean Abs Dev is lower,that field is First?
I tested some MPEG2 sources captured by MPEG-2 capture board and using MPEG2DEC.dll(by dividee).
By using your function,the value of bottom field is lower in Avg Mean Abs Dev than top.
Does that result mean BottomFirst?
But,I think my sources should be TopFirst.
For example,when I use TMPGEnc and DVD2AVI,they always judge my MPEG2 videos as TopFirst.
Why did these differeneces happened?
Or,does Avisynth always assume a clip is bottom field first?
Any idea?
My AVS is like this:
LoadPlugin("mpeg2dec.dll")
v=Mpeg2Source("D:\test.d2v")
function CheckTopFirst(clip v1){
t0=v1.ComplementParity
t1=t0.separatefields
t2=compare(t1.trim(1,0),t1)
b1=v1.separatefields
b2=compare(b1.trim(1,0),b1)
return stackvertical(t2,b2)}
CheckTopFirst(v)
trbarry
28th September 2002, 20:25
niiyan -
Yes, the one (top or bottom) with the lower abs dev is probaly the correct answer to be first. But as a sanity check it should probably also be less jerky in preview, and I think also will probably have a HIGHER avg PSNR value.
I can't explain the differences with Tmpg. But be careful you don't do it on a trailer, preview, lead-in, etc. Make sure to look at the body of the movie, probably in multiple places if there is any doubt.
I think (like siwalters said above) Avisynth just assumes Bottom First unless you issue a ComplementParity statement. But I don't know if Avisynth passes this to Tmpg or anywhere else.
- Tom
Marc FD
28th September 2002, 21:47
i know i've inverted the parity value in MPEG2DecPP (finally i need to give this a name)
because it seemed to be always false.
niiyan
29th September 2002, 17:42
@trbarry
I tested again your function by using a movie,of course the body of a movie and in several scenes.
The movie was captured by a MPEG2 capturing board from TV.
So,the result is almost the same as yesterday.
1.About Avg Mean Abs Dev,the most of the bottom clip is lower than the top one.
2.But,in the some scene,the top value is sometimes lower.
3.When Avg Mean Abs Dev is lower in the bottom field,avg PSNR value is higher in the bottom.
Sorry,it's difficult for me to judge if it's jerky or less jerky.
In this result,do you think the movie is BottomFirst?
By the way,Wilbert's Getparity script says TopFirst.
Si
29th September 2002, 17:55
@niiyan
Are you sure you get Topfirst from Wilberts script or do you have any other items in the script? :confused:
Could you post the exact script used?
regards
Simon
niiyan
29th September 2002, 18:54
@siwalters
My avs is like this:
LoadPlugin("mpeg2dec.dll")
Mpeg2Source("D:\test.d2v")
subtitle(last.GetParity() ? "TopFirst":"BottomFirst", font="MS UI Gothic")
Mm...,my script is a little bit different from Wilbert one.
But is this the same thing?
-niiyan
Si
29th September 2002, 22:23
@niiyan
Mpeg2Source may be able to query the MPEG file TFF(Top Field First) flag and return its state.
OR it may just change the Parity flag regardless?
Unfortunately, Mpeg2Source doesn't seem to work on my system so I can't do any tests with it :( (But maybe someone else could check)
@niiyan again
Could you save an avi from your script and then use Wilbert's script on that avi and see what you get?
regards
Simon
niiyan
30th September 2002, 17:40
@siwalters
I tested UnRecompressed avi and DivX codec avi.
Both are captured as MPEG2 and encoded by AviUtl or VirtualDub.
When I use those AVI files,Getparity script shows BottomFirst.
-niiyan
Si
30th September 2002, 18:06
Phew - I was getting worried :)
If anyones got the time (and the system that Mpeg2Source works on) maybe they could post some results with an MPEG-2 TFF=true and TFF =false to see if its being picked up correctly
regards
Simon
WarpEnterprises
30th September 2002, 21:32
MPEG2SOURCE does it correctly - tested.
Si
30th September 2002, 22:39
@Warp - thanks
I've updated a few filter descriptions in the Wiki to let others know.
regards
Simon
Marc FD
1st October 2002, 15:47
Originally posted by WarpEnterprises
MPEG2SOURCE does it correctly - tested.
can you test with mine please ?
i've changed some parity code.
thx a lot.
trbarry
1st October 2002, 23:43
I previously thought that Avisynth always assumed Bottom First unless you changed it. But apparently MPEG2DEC.dll and possibly some other codecs or access methods will set it for you.
This is nice but makes my function above give the wrong results in some cases. So I changed it. The following updated version will also print "TF" or "BF" in the upper left hand corner, telling what Avisynth thinks it currently is. It looks so far as if Avisynth is probably correct when using MPEG2DEC2 but not for mjpeg or maybe some others.
function CheckTopFirst(clip v1){
v2=v1.subtitle(v1.GetParity?"TF":"BF")
v3=v2.GetParity?v2.ComplementParity:v2
t0=v3.ComplementParity
t1=t0.separatefields
t2=compare(t1.trim(1,0),t1)
b1=v3.separatefields
b2=compare(b1.trim(1,0),b1)
return stackvertical(t2,b2)}
Hopefully the results of all three checks ("TF/BF", avg mean dev, jerkiness) will agree but when they don't I guess you are on your own. ;)
- Tom
niiyan
2nd October 2002, 16:34
@trbarry
Nice work!!
I tested your updated function.
I used a few MPEG2 sources from TV.
This time,all three checks (and also PSNR) agreed.
Thanks a lot,Tom.
-niiyan
sh0dan
17th June 2003, 17:27
Does this function make any sense??
My lack of interlaced clips at home makes it quite hard to test.
(Scroll down for an improved version)
It should write a guess on parity on top of the frame.
Boulder
17th June 2003, 18:12
On my TV caps the script guesses both true and false and there's no pattern, just randomly true or false.
bilu
17th June 2003, 18:22
@Sh0dan
It should be as hard to tell as the metrics problem in Decomb I think.You can allways get static scenes, low-motion, blended fields....
But still I didn't quite got your line of though, could you explain your conditional filtering please?
Bilu
trbarry
17th June 2003, 19:47
can you test with mine please ?
i've changed some parity code.
Marc FD (and now Nic) -
Well, better late than never. ;)
MPEG2DEC3 does now seem to return the correct parity. This is nice because then you can use -1 (auto) for the Top First value in TomsMoComp.
On my TV caps the script guesses both true and false and there's no pattern, just randomly true or false
Boulder -
It will jump around but if you look at the average numbers in the middle colum it should quickly converge to show which is better. And if that is not obvious then just preview the results. Either the top or bottom will be jerkier, so assume the other.
- Tom
sh0dan
17th June 2003, 20:21
On my artificially created clips it works most of the time.
I added some stats (percentwise bff/tff reporting).
function CheckTopFirst(clip v1){
global top_hits=1
global bot_hits=1
global text = ""
global text2 = ""
v1 = assumeframebased(v1)
global tff=assumetff(v1).separatefields().bob()
global bff=assumebff(v1).separatefields().bob()
istff = tff.subtitle("Is frame TFF: TRUE").frameevaluate("top_hits=top_hits+1.0")
isnottff = tff.subtitle("Is frame TFF: FALSE").frameevaluate("bot_hits=bot_hits+1.0")
outclip = conditionalfilter(tff,istff, isnottff, "yDifferenceFromPrevious(tff)+ydifferenceToNext(tff)","<","yDifferenceFromPrevious(bff)+yDifferenceToNext(bff)",false)
outclip = frameevaluate(outclip,"text = "+chr(34)+"STATS: TFF = "+chr(34)+" + string(100.0*top_hits/(top_hits+bot_hits)) + " + chr(34) + "%"+chr(34))
outclip = frameevaluate(outclip,"text2 = "+chr(34)+"STATS: BFF = "+chr(34)+" + string(100.0*bot_hits/(top_hits+bot_hits)) + " + chr(34) + "%"+chr(34))
outclip = scriptclip(outclip, "Subtitle(text,y=50)")
outclip = scriptclip(outclip, "Subtitle(text2,y=70)")
return outclip
}
It simply does two separatefields - one with bff and one with tff. Then it compares the current frame to the previous, and it reports whether bff or tff has the least difference.
This assumes that streams with correct parity will be more similar to the previous and next frame. Wrong parity causes "jumping frames", which gives more difference to the previous and next frame.
I seems this is the same method trbarry used - only with a bit more "reporting". Be sure to run for as many frames as needed, and possibly at different locations in the movie.
Edit: Corrected minor mistake - should be more accurate now!
Boulder
17th June 2003, 20:22
Originally posted by trbarry
Boulder -
It will jump around but if you look at the average numbers in the middle colum it should quickly converge to show which is better. And if that is not obvious then just preview the results. Either the top or bottom will be jerkier, so assume the other.
- Tom
Hehe, I was referring to sh0dan's script in my last post;)
I've used your script before and the average value has been correct every time, although if the values have been nearly the same, I've used the preview to doublecheck.
EDIT: sh0dan - that latter script of yours works on my material, the percentage is about 66 - 33 in favour of TopFirst, which previewing with Tom's original script proves to be true. Nice work! :)
trbarry
17th June 2003, 20:27
Who usually maintains the compare function? My script uses that but it doesn't seem to support YV12 yet?
So you will have to put a ConvertToYUY2() first.
- Tom
sh0dan
17th June 2003, 20:42
@trbarry: dividee made and maintained it. It's a mess IMHO, and I would rather rewrite it before adding new features to it. Just never got around to doing it.
Luckily my script requires YV12 - so they supplement eachother nicely. ;)
Edit: The script has been updated for better accuracy - you should update!
WarpEnterprises
18th June 2003, 07:18
OT: where is dividee anyway?
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.