Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 23rd December 2010, 14:22   #1  |  Link
Kuukunen
Registered User
 
Join Date: Apr 2007
Posts: 61
Script for fixing corrupted frames

So, I was helping some guy with a capture video that had some borked frames. Luckily they were usually just one or two. So I made a simplistic filter for detecting frames with too much blocks and interpolating them. (Or deblocking heavily for scenes with too much motion.)

It's pretty specific thing, so I've no idea if anyone has any use for it. It might also horribly fail with some sources. It's also very slow script for something that should be done manually anyway. :P

There's lots that could be improved. Like primary detection to check if a frame is even worth calculating further. (For speed.) Actually the whole script should be done as a two-pass filter and a custom shell/perl/ruby script in between that handles logs and decides what to do, based on how long the streams of broken frames are etc.

I've even no idea if similar things exist, I wrote it mainly for fun. I guess if someone needs to make a conditional script for handling blocky frames, this could be a good starting point. (I could make a generalized script for that, but meh.)

Btw, anyone know if parts of the script that are inside conditional filter inside eval that fail the condition are processed? (Or are they just wasting speed there?) I'd guess they're not, but not 100% sure.

Code:
# QQfix v0.36
# This function tries to identify corrupted (blocky) frames and fix them by interpolating from previous and next frames
# It does this by counting edges at 8x8 block positions. Which means it assumes blocks start from top left
# It doesn't do anything to frames it doesn't detect as blocked
# It deblocks the frames it tries to fix, but you probably still want to run deblock(_qed) on the entire video anyway
# In frames with too much motion (ydifferencefromprevious > diffthres) it's not interpolated, but heavily deblocked
# Use debug=true to determine good values for your video or if this script is even useful
# By: Kuukunen

function qqfix(clip v, int "blockthres", float "messthres", float "diffthres", int "delta",bool "debug") {

blockthres=default(blockthres, 18) # how likely an edge is to be counted as a block edge
messthres=default(messthres,1.5) # how much block edges there needs to be to be considered corrupted (VERY dependent on blockthres)
diffthres=default(diffthres,15) # if frame changes this much from last frame and gets detected, don't do interpolation, but do heavy deblocking instead
delta=default(delta,1) # how far to calculate fixes from: more = longer corruptions handled, but 
debug=default(debug,false) #instead of fixing anything, show debugging information

padX = v.width%8 == 0 ? 0 : (8 - v.width%8)
padY = v.height%8 == 0 ? 0 : (8 - v.height%8)
v=v.addborders(0, 0, padX, padY)

v2 = v.Levels(0, 2, 255, 0, 255)
sub = subtract(v2,v2.deblock_qed(30,30))
db = v.deblock_qed(30,30)

vedge2 = v.mt_LutSpa(relative=false, expr="x 8 % 1 < 255 0 ?")
vedge1 = v.mt_LutSpa(relative=false, expr="1 x + 8 % 1 < 255 0 ?")
hedge2 = v.mt_LutSpa(relative=false, expr="y 8 % 1 < 255 0 ?")
hedge1 = v.mt_LutSpa(relative=false, expr="1 y + 8 % 1 < 255 0 ?")


vm1=sub.converttorgb().GeneralConvolution(0, "0  0  0 0  -1  1 0 0 0 ", 1)
vm1=blankclip(sub).overlay(vm1,mask=vedge1).mt_binarize(blockthres)
vm1=vm1.bilinearresize(vm1.width,vm1.height/8).mt_binarize(220).pointresize(vm1.width,vm1.height)

vm2=sub.converttorgb().GeneralConvolution(0, "0 0 0 1  -1  0 0 0 0 ", 1)
vm2=blankclip(sub).overlay(vm2,mask=vedge2).mt_binarize(blockthres)
vm2=vm2.bilinearresize(vm2.width,vm2.height/8).mt_binarize(220).pointresize(vm2.width,vm2.height)

hm1=sub.converttorgb().GeneralConvolution(0, "0  0  0 0  -1  0 0 1 0 ", 1)
hm1=blankclip(sub).overlay(hm1,mask=hedge1).mt_binarize(blockthres)
hm1=hm1.bilinearresize(hm1.width/8,hm1.height).mt_binarize(220).pointresize(hm1.width,hm1.height)

hm2=sub.converttorgb().GeneralConvolution(0, "0  1  0 0 -1  0 0 0 0 ", 1)
hm2=blankclip(sub).overlay(hm2,mask=hedge2).mt_binarize(blockthres)
hm2=hm2.bilinearresize(hm2.width/8,hm2.height).mt_binarize(220).pointresize(hm2.width,hm2.height)

vm=mt_logic(vm1,vm2,"or")
hm=mt_logic(hm1,hm2,"or")
m=mt_logic(vm,hm,"or")
db
super = MSuper()
backward_vectors = MAnalyse(super, isb = true, delta=delta)
forward_vectors = MAnalyse(super, isb = false, delta=delta)
inter = MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70)

d1 = v2.scriptclip("""subtitle("YDifference: " + String(ydifferencefromprevious()))""")
d2 = v2.scriptclip("""subtitle("YDifference: " + String(ydifferencefromprevious()))""").subtitle("High motion!", y=20)
dc = conditionalfilter(v,d2,d1,"ydifferencefromprevious()", ">", String(diffthres))

v=debug?dc:v

debug?Eval("""
   v=conditionalfilter(m,v,v,"averageluma()",">",String(messthres),true)
   v=v.tweak(cont=0.5).overlay(m,mask=m)
"""):Eval("""
   vi=conditionalfilter(m,inter,v,"averageluma()",">",String(messthres))
   v=conditionalfilter(v,db,vi,"ydifferencefromprevious()", ">", String(diffthres))
""")
return v.crop(0, 0, -padX, -padY)
}

Last edited by Kuukunen; 23rd December 2010 at 15:55.
Kuukunen is offline   Reply With Quote
Old 23rd December 2010, 14:59   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by Kuukunen View Post
anyone know if parts of the script that are inside conditional filter inside eval that fail the condition are processed? (Or are they just wasting speed there?) I'd guess they're not, but not 100% sure.
With ConditionalFilter(a, b, c, ... test ...), for each frame of 'a', a frame is always fetched from either 'b' or 'c' (but never both) depending on the result of the test (for that frame).

There are some odd bits in your code:
Quote:
Code:
v=conditionalfilter(m,v,v,"averageluma()",">",String(messthres),true)
   blankclip(v).overlay(v,mask=m)
   v=v.tweak(cont=0.5).overlay(m,mask=m)
The first line is equivalent to v=v.
The second line is never used as its result is thrown away.

Also in this code:
Quote:
Code:
d2 = v2.scriptclip("""subtitle("YDifference: " + String(ydifferencefromprevious()))""").scriptclip("""subtitle("High motion!", y=20)""")
The second subtitle need not be inside a ScriptClip as its text is the same for all frames. Subtitle inside ScriptClip is particularly slow.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 23rd December 2010, 16:05   #3  |  Link
Kuukunen
Registered User
 
Join Date: Apr 2007
Posts: 61
Quote:
Originally Posted by Gavino View Post
With ConditionalFilter(a, b, c, ... test ...), for each frame of 'a', a frame is always fetched from either 'b' or 'c' (but never both) depending on the result of the test (for that frame).
That's what I was figuring, but I was just a bit afraid the combination with Eval might cause it to be thrown off and cause it to process both.

Quote:
Originally Posted by Gavino View Post
The first line is equivalent to v=v.
Not true. Notice the "true" at the end. It prints the debug info. :p
Yea I was being very lazy, but not like the speed difference is to great when compared to the other mess, and it's in debug mode anyway.
Quote:
Originally Posted by Gavino View Post
The second line is never used as its result is thrown away.
This one's true. It's a leftover from an older version and it used to be commented. Dunno why it's not in this version.

Quote:
Originally Posted by Gavino View Post
The second subtitle need not be inside a ScriptClip as its text is the same for all frames. Subtitle inside ScriptClip is particularly slow.
Ah yea. I was playing around a lot with it, so I left in the inefficient version. (Altho it's in debug mode too, so doesn't matter too much) I couldn't figure out a way to do something like
Eval("""Scriptclip("Subtitle(\"Hello: \" + String(YDifferenceFromPrevious()))")""")
In essence, three nested quotes. I tried some other quote chars (as suggested in avisynth wiki) but couldn't get it to work.
Kuukunen is offline   Reply With Quote
Old 23rd December 2010, 16:20   #4  |  Link
Kuukunen
Registered User
 
Join Date: Apr 2007
Posts: 61
Oh yea, here are some test frames from my cap.
_borken is borken, _fixed is fixed and debug is debug=true.

Now that I look at it with the newest version of the script, I guess the thresholds might need some further tweaking... But should get the idea across.

http://kuukunen.net/misc/qqfix/
Kuukunen is offline   Reply With Quote
Old 23rd December 2010, 16:52   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by Kuukunen View Post
Not true. Notice the "true" at the end. It prints the debug info.
Yes, sorry, I overlooked the [show=]true.
Quote:
I couldn't figure out a way to do something like
Eval("""Scriptclip("Subtitle(\"Hello: \" + String(YDifferenceFromPrevious()))")""")
In essence, three nested quotes. I tried some other quote chars (as suggested in avisynth wiki) but couldn't get it to work.
The other quote chars mentioned in the wiki are for displaying quotes in a subtitle, but don't work for delimiting Avisynth strings.
You would need to do it in stages to break up the nesting, eg:
h = "Hello"
Eval("""Scriptclip("Subtitle(h + String(YDifferenceFromPrevious()))")""")
(although in this specific example Eval is actually redundant).
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 23rd December 2010, 17:08   #6  |  Link
Kuukunen
Registered User
 
Join Date: Apr 2007
Posts: 61
Quote:
Originally Posted by Gavino View Post
h = "Hello"
Eval("""Scriptclip("Subtitle(h + String(YDifferenceFromPrevious()))")""")
Err, wth. I'm sure I tried that too. It was always complaining about not finding h. I guess I typo'd something then.
Kuukunen is offline   Reply With Quote
Old 23rd December 2010, 17:24   #7  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by Kuukunen View Post
Err, wth. I'm sure I tried that too. It was always complaining about not finding h. I guess I typo'd something then.
If 'h' is a local variable (ie inside a function), it will be out of scope at runtime when interpreted inside ScriptClip.
In that case, you could rewrite the example as
s = """Subtitle("Hello" + String(YDifferenceFromPrevious()))"""
Eval("Scriptclip(s)")
as 's' will be evaluated at compile-time (though Eval is still redundant ).

Alternatively, use GRunT's extended ScriptClip:
ScriptClip("Subtitle(h + String(YDifferenceFromPrevious()))", args="h")
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 23rd December 2010 at 19:52. Reason: Correct code
Gavino is offline   Reply With Quote
Old 23rd December 2010, 19:21   #8  |  Link
Kuukunen
Registered User
 
Join Date: Apr 2007
Posts: 61
Well I figured it has to be some weird scoping issue. Didn't know it worked with global variables.
How silly Scriptclip is not in the same scope.

Hmm, ideas for a (possible) next version:
* Use MMask instead of YDifferenceFromPrevious.
* Possibly don't do interpolation if previous and next frames are also detected. (Although if it's only one pass, this might make it a bit slower, but only for frames which are detected and there shouldn't be too many of those, so I guess it's ok.)
* Two pass mode. Too much effort though.
* Would be so much faster and more flexible as a real filter it's not even funny. Too much effort though.

Last edited by Kuukunen; 23rd December 2010 at 21:36. Reason: interpolation, not deinterlacing
Kuukunen is offline   Reply With Quote
Old 23rd December 2010, 20:06   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by Kuukunen View Post
How silly Scriptclip is not in the same scope.
It's basically because the script passed to ScriptClip is interpreted at a later time (filter 'runtime'), when local variables have gone out of scope. See here.

What is missing from the original design of ScriptClip (and similar filters) is a way of making a binding between variables in-scope at the ScriptClip call and variables in the inner script. GRunT rectifies this deficiency.

(Sorry for hijacking the main point of your thread with one of my pet hobby-horses. )
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 7th January 2011, 00:09   #10  |  Link
chani
Registered User
 
Join Date: Dec 2010
Posts: 2
hey,

thanks @ kuukunen for creating that function for me, does a fine job so far

This "blocky" stuff happens a lot on dvb-t captured material. Especially if you got a bad antenna. For example my bought active 42db amplified (yeah....) antenna gives such results. While my selfmade dipol antenna (which i created for testing purposes a year later) is way better. However, i guess everyone playing dvb-t has to deal with such problems.

At DVB-S i see such blocky stuff, also though not as much. On DVB-C i never saw something like that.
__________________
a computer without windows is like a chocolatecake without mustard
chani is offline   Reply With Quote
Old 6th December 2013, 05:07   #11  |  Link
junh1024
Registered User
 
Join Date: Mar 2011
Posts: 59
Updated to work with avs 2.6 (with the help of Kuukunen). No idea if my changes are correct or useful.

Code:
# QQfix v0.36h
# This function tries to identify corrupted (blocky) frames and fix them by interpolating from previous and next frames
# It does this by counting edges at 8x8 block positions. Which means it assumes blocks start from top left
# It doesn't do anything to frames it doesn't detect as blocked
# It deblocks the frames it tries to fix, but you probably still want to run deblock(_qed) on the entire video anyway
# In frames with too much motion (ydifferencefromprevious > diffthres) it's not interpolated, but heavily deblocked
# Use debug=true to determine good values for your video or if this script is even useful
# By: Kuukunen

function qqfix(clip v, int "blockthres", float "messthres", float "diffthres", int "delta",bool "debug") {

blockthres=default(blockthres, 18) # how likely an edge is to be counted as a block edge
messthres=default(messthres,1.5) # how much block edges there needs to be to be considered corrupted (VERY dependent on blockthres)
diffthres=default(diffthres,15) # if frame changes this much from last frame and gets detected, don't do interpolation, but do heavy deblocking instead
delta=default(delta,1) # how far to calculate fixes from: more = longer corruptions handled, but 
debug=default(debug,false) #instead of fixing anything, show debugging information

padX = v.width%16 == 0 ? 0 : (16 - v.width%16)
padY = v.height%16 == 0 ? 0 : (16 - v.height%16)
v=v.addborders(0, 0, padX, padY)

v2 = v.Levels(0, 2, 255, 0, 255)
sub = subtract(v2,v2.deblock_qed(30,30))
db = v.deblock_qed(30,30)

vedge2 = v.mt_LutSpa(relative=false, expr="x 8 % 1 < 255 0 ?")
vedge1 = v.mt_LutSpa(relative=false, expr="1 x + 8 % 1 < 255 0 ?")
hedge2 = v.mt_LutSpa(relative=false, expr="y 8 % 1 < 255 0 ?")
hedge1 = v.mt_LutSpa(relative=false, expr="1 y + 8 % 1 < 255 0 ?")


vm1=sub.mt_convolution("0 -1 1","1",true, 1.0)
vm1=blankclip(sub).overlay(vm1,mask=vedge1).mt_binarize(blockthres)
vm1=vm1.bilinearresize(vm1.width,vm1.height/8).mt_binarize(220).pointresize(vm1.width,vm1.height)

vm2=sub.mt_convolution("1 -1 0","1",true, 1.0)
vm2=blankclip(sub).overlay(vm2,mask=vedge2).mt_binarize(blockthres)
vm2=vm2.bilinearresize(vm2.width,vm2.height/8).mt_binarize(220).pointresize(vm2.width,vm2.height)

hm1=sub.mt_convolution("0 1 0", "0 -1 1",true, 1.0)
hm1=blankclip(sub).overlay(hm1,mask=hedge1).mt_binarize(blockthres)
hm1=hm1.bilinearresize(hm1.width/8,hm1.height).mt_binarize(220).pointresize(hm1.width,hm1.height)

hm2=sub.mt_convolution("0 1 0","1 -1 0",true, 1.0)
hm2=blankclip(sub).overlay(hm2,mask=hedge2).mt_binarize(blockthres)
hm2=hm2.bilinearresize(hm2.width/8,hm2.height).mt_binarize(220).pointresize(hm2.width,hm2.height)

vm=mt_logic(vm1,vm2,"or")
hm=mt_logic(hm1,hm2,"or")
m=mt_logic(vm,hm,"or")
db
super = MSuper()
backward_vectors = MAnalyse(super, isb = true, delta=delta)
forward_vectors = MAnalyse(super, isb = false, delta=delta)
inter = MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70)

d1 = v2.scriptclip("""subtitle("YDifference: " + String(ydifferencefromprevious()))""")
d2 = v2.scriptclip("""subtitle("YDifference: " + String(ydifferencefromprevious()))""").subtitle("High motion!", y=20)
dc = conditionalfilter(v,d2,d1,"ydifferencefromprevious()", ">", String(diffthres))

v=debug?dc:v

debug?Eval("""
   v=conditionalfilter(m,v,v,"averageluma()",">",String(messthres),true)
   v=v.tweak(cont=0.5).overlay(m,mask=m)
"""):Eval("""
   vi=conditionalfilter(m,inter,v,"averageluma()",">",String(messthres))
   v=conditionalfilter(v,db,vi,"ydifferencefromprevious()", ">", String(diffthres))
""")
return v.crop(0, 0, -padX, -padY)
}
junh1024 is offline   Reply With Quote
Old 6th December 2013, 07:48   #12  |  Link
turbojet
Registered User
 
Join Date: May 2008
Posts: 1,840
Interesting, never knew there was a script that does something like this. I get corrupt frames on rare occasions that look a lot like http://forum.doom9.org/showthread.php?t=169684 qqfix helps a bit but it doesn't achieve the expected interpolated results. I tried tweaking the thresholds to no avail, any suggestions?

Were you aware of a 0.95 that has different defaults and more options and is also about 33% faster? The results between the 2 are comparable on the source I mentioned.
__________________
PC: FX-8320 GTS250 HTPC: G1610 GTX650
PotPlayer/MPC-BE LAVFilters MadVR-Bicubic75AR/Lanczos4AR/Lanczos4AR LumaSharpen -Strength0.9-Pattern3-Clamp0.1-OffsetBias2.0
turbojet is offline   Reply With Quote
Old 6th December 2013, 12:30   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
From TurboJet supplied link to qqfix v0.95 on kuukunen's web page, uploaded yesterday. Given here in entirety.

Code:
# qqfix v0.95
#
# Important! Read this first! The defaults probably won't work properly and this can do much more harm than good!
#
# This filter is meant for a very specific kind of corrupted video: where the video has occasional SINGLE corrupted frames surrounded by
# good frames. It detects corruption by estimating the blockiness of the video and then discarding the frame completely and constructing
# it from the surrounding frames. It assumes the block edges are at 8x8 positions, so if there has been scaling or moving the picture,
# it won't work properly.
#
# Some videos have corruption where the frames are blocky, but otherwise almost correct and some videos have corrupted frames that
# are completely incorrect. Therefore you can conditionally filter based on luma difference in two ways. Fixing only frames with
# luma difference lower than threshold can prevent breaking high motion frames that wouldn't get fixed properly and fixing only
# frames with luma difference higher than threshold can limit fixing to frames that are completely broken.
#
# How to use filter:
#
# First you must get an idea about the overall blockiness of your video. This is very dependent on the video and there's no way
# for the defaults to work for every video.
#
# You can do this by turning on the "debug" mode by setting debug parameter to true. The debug mode will indicate which edges
# have been detected as a block edge with white lines. The amount of detected block edges will be summed up as "blockiness"
# value and shown in top left corner. If this value is higher than the threshold (shown below it), that frame will be discarded
# and interpolated.
#
# The blockthres parameter will be the threshold used for determining if an edge is a block edge or not. Adjust this to the value
# that gives the most difference between the blockiness value of corrupted frames and good frames. Then set messthres to
# value between the lowest corrupted frame value and highest good frame value. And hope those two don't overlap.
#
# Debug mode will show text "Corrupted!" if it thinks the frame is corrupted and needs to be filtered.
#
# If you set diffthres to some number, it will show the luma difference to the right from the blockiness display.
# If you don't set invertdiff or set it to false, it will NOT fix frames with higher luma difference than the  diffthres.
# It will indicate this by showing the text "Ignore!", and those frames won't get filtered even if they show "Corrupted!"
#
# Parameters:
#
# blockthres:
# range 0.0-1.0. default 0.03
# This is used to determine how strong the edge has to be for it to get detected as a block edge. Just tweak it in debug
# mode until you get good results.
#
# messthres:
# range 0.0-255.0, default 4
# This is used to select corrupted frames based on the blockiness and then messing with them.
#
# diffthres:
# range 0.0-255.0, default off
# This can be used to limit filtering only to frames below or above certain luma difference between current and previous frame.
#
# invertdiff:
# default: false
# If set to false or left out, only frames with luma difference LOWER than diffthres will get fixed. If set to true, frames with
# luma difference HIGHER than diffthres will get filtered.
#
# delta:
# range 1-> default: 1
# Used for determining how far the frames are fetched when interpolating. Using values higher than 1 are probably going to cause
# problems unless the video is very slow motion. However, in theory setting this to 2 would allow the filter to work for
# video that has two corrupted frames. (Because it ignores the next frame and uses the one after that instead.)
#
# debug:
# default: false
# Show debug information. See above for more details.

function qqfix(clip v, int "blockthres", float "messthres", float "diffthres", bool "invertdiff", int "delta", bool "debug") {

blockthres=default(blockthres, 0.03)
messthres=default(messthres, 4)
diffthres=default(diffthres,10000)
invertdiff=default(invertdiff,false)
delta=default(delta,1)
debug=default(debug,false)

padX = (16 - v.width%16)%16
padY = (16 - v.height%16)%16
v=v.addborders(0, 0, padX, padY)

v2 = v.Levels(0, 2, 255, 0, 255)
vedges = v.mt_lutspa(relative=false, expr="x 8 % 1 < 255 0 ?")
hedges = v.mt_lutspa(relative=false, expr="y 8 % 1 < 255 0 ?")

vedgem = v2.mt_convolution("1 -1 0", "1", false, 1.0)
vm = vedgem.mt_lutxy(vedgem.mt_convolution("1 0 1", "1"), "x y -").mt_logic(vedges, "min")
vm = vm.bilinearresize(vm.width,vm.height/8).pointresize(vm.width,vm.height).mt_binarize(int(blockthres*255))

hedgem = v2.mt_convolution("1", "1 -1 0", false, 1.0)
hm = hedgem.mt_lutxy(hedgem.mt_convolution("1", "1 0 1"), "x y -").mt_logic(hedges, "min")
hm = hm.bilinearresize(hm.width/8,hm.height).pointresize(hm.width,hm.height).mt_binarize(int(blockthres*255))

m=mt_logic(vm,hm,"or").greyscale()

v
super = MSuper()
backward_vectors = MAnalyse(super, isb = true, delta=delta)
forward_vectors = MAnalyse(super, isb = false, delta=delta)
inter = MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70)

global qqfixm = m
global qqfixv = v
debugclip = mt_lutxy(v.tweak(cont=0.7), m, "x y +")
debugclip = debugclip.scriptclip("""subtitle("Blockiness: " + String(qqblockiness), 10, 10)""")
debugclip = debugclip.frameevaluate("qqblockiness = qqfixm.averageluma()")
debugclip = debugclip.subtitle("Threshold: " + string(float(messthres)), 10, 30)
debugclipCorrupted = debugclip.subtitle("Corrupted!", 10, 50)
debugclip = conditionalfilter(m,debugclipCorrupted,debugclip,"averageluma()",">",String(messthres))

diffoper = invertdiff ? "<" : ">"

diffdebugclip = debugclip.scriptclip("""subtitle("Luma Difference: " + String(qqydiff), 200, 10)""")
diffdebugclip = diffdebugclip.frameevaluate("qqydiff = qqfixv.ydifferencefromprevious()")
diffdebugclip = diffdebugclip.subtitle("Threshold: " + string(float(diffthres)), 200, 30)
diffdebugclipIgnored = diffdebugclip.subtitle("Ignore!", 200, 50)
diffdebugclip = conditionalfilter(v,diffdebugclipIgnored,diffdebugclip,"ydifferencefromprevious()",diffoper,String(diffthres))

debugclip = diffthres < 10000? diffdebugclip : debugclip

filtered = conditionalfilter(m,inter,v,"averageluma()",">",String(messthres))
final = conditionalfilter(v,v,filtered,"ydifferencefromprevious()", diffoper, String(diffthres))

return (debug?debugclip:final).crop(0, 0, -padX, -padY)
}
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 15th December 2013, 08:58   #14  |  Link
junh1024
Registered User
 
Join Date: Mar 2011
Posts: 59
Kuukunen , i tested your new QQFix. On this particular boating motorsport TV show that I recorded, using it seems not so appropriate because the show is a mix of SD/HD 25p/50i shots , and each section requires different thresholds to be set (which i'm not willing to take the effort to go sectional).

Nevertheless, thank you for the rewrite - debug mode is now much more intuitive, and increased speed is always welcome. I may use it in the future.
junh1024 is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 10:20.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.