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. |
27th January 2005, 02:14 | #1 | Link |
defkunt
Join Date: Dec 2004
Location: New Zealand
Posts: 58
|
Modified QMF
If my understanding of XVID is correct one thing it will benefit from is a steady stream of consistant information, allowing it to reuse blocks from other frames particularly I-Frames on scene changes.
In which case, one problem with QMF is that it evaluates the first frame of a new scene (presumably an I-Frame) as high motion, which given its intended use will be a frame with less detail than a low motion frame even when the scene that follows is low motion. So I've messed about with the original script to make it detect scene changes (I find a threshold of 24 pretty accurate) and then treat that frame as it would the frame that follows. I also added another level of motion but think that this is probably fairly gratuitous and unneccesary. Thoughts? Code:
function Motion() { global motion_level = 0 global motion_level = (diff > threshold_zm) ? 1 : motion_level global motion_level = (diff > threshold_lm) ? 2 : motion_level global motion_level = (diff > threshold_hm) ? 3 : motion_level global motion_level = (diff > threshold_sc) ? 4 : motion_level } function Change() { global motion_level = (next > threshold_zm && motion_level > 3) ? 5 : motion_level global motion_level = (next > threshold_lm && motion_level > 3) ? 6 : motion_level global motion_level = (next > threshold_hm && motion_level > 3) ? 7 : motion_level } function QMF(clip c, float "threshold_zm", float "threshold_lm", float "threshold_hm", float "threshold_sc", bool "debug") { global threshold_zm = default(threshold_zm, 3.0) global threshold_lm = default(threshold_lm, 6.0) global threshold_hm = default(threshold_hm, 12.0) global threshold_sc = default(threshold_sc, 24.0) global motion_level = 0 global clip = c c = ConditionalFilter(c, Filter_Motion_Nil(c), c, "motion_level", "=", "0") c = ConditionalFilter(c, Filter_Motion_Min(c), c, "motion_level", "=", "1") c = ConditionalFilter(c, Filter_Motion_Mid(c), c, "motion_level", "=", "2") c = ConditionalFilter(c, Filter_Motion_Max(c), c, "motion_level", "=", "3") c = ConditionalFilter(c, Filter_Motion_Nil(c), c, "motion_level", "=", "4") c = ConditionalFilter(c, Filter_Motion_Min(c), c, "motion_level", "=", "5") c = ConditionalFilter(c, Filter_Motion_Mid(c), c, "motion_level", "=", "6") c = ConditionalFilter(c, Filter_Motion_Max(c), c, "motion_level", "=", "7") c = (default(debug, false)) == true ? ScriptClip(c, "Debug()") : c c = FrameEvaluate(c, "Change()") c = FrameEvaluate(c, "global next = (0.50 * YDifferenceToNext(clip)) + (0.25 * UDifferenceToNext(clip)) + (0.25 * VDifferenceToNext(clip))") c = FrameEvaluate(c, "Motion()") c = FrameEvaluate(c, "global diff = (0.50 * YDifferenceFromPrevious(clip)) + (0.25 * UDifferenceFromPrevious(clip)) + (0.25 * VDifferenceFromPrevious(clip))") return c } function Debug(clip c) { c = Subtitle(c, "Motion Evaluation: " + string(diff), x=25, y=150, font="courier new", size=24) c = (motion_level == 0) ? Subtitle(c, "Zero Motion Frame", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 1) ? Subtitle(c, "Low Motion Frame", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 2) ? Subtitle(c, "Medium Motion Frame", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 3) ? Subtitle(c, "High Motion Frame", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 4) ? Subtitle(c, "Scene Change (Zero)", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 5) ? Subtitle(c, "Scene Change (Low)", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 6) ? Subtitle(c, "Scene Change (Medium)", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c c = (motion_level == 7) ? Subtitle(c, "Scene Change (High)", x=25, y=200, font="courier new", size=32, text_color=$FFFFFF) : c return c } |
18th July 2005, 17:29 | #3 | Link |
Registered User
Join Date: Oct 2001
Posts: 62
|
Is that modification based on the latest Qmf 1.5 b1 ?
'Cause that was apparently the latest released version but all the downloadlinks in the old threads are down and I couldn't find a mirror via Google, that's why I can't compare. |
18th July 2005, 20:45 | #5 | Link |
defkunt
Join Date: Dec 2004
Location: New Zealand
Posts: 58
|
The script as posted is only a fragment, it was also line broken on the longer lines (so as not to make the post too wide). You can grap a more complete implementation here. Have enabled debug mode QMF(..., debug=true) so you can see what decisions the script is making, runs much faster without this. The functions:
Filter_Motion_Nil(clip base) Filter_Motion_Min(clip base) Filter_Motion_Mid(clip base) Filter_Motion_Max(clip base) ...presently do nothing but return the clip they are passed. Use these to perform your own processing based on the frame type. Hope this helps. |
18th July 2005, 22:04 | #6 | Link |
Registered User
Join Date: May 2002
Posts: 384
|
Thanks, got it working. The scenechanges no longer look blurry compared to frames after it in low motion scenes. It does seem to be more switch-happy during scenes itself though, compared to original qmf. Especially apparent when theres sudden motion in relative quiet scenes. Most likely it's a matter of further tweaking.
|
19th July 2005, 07:36 | #7 | Link |
defkunt
Join Date: Dec 2004
Location: New Zealand
Posts: 58
|
Keep in mind that I added a fourth level of motion separation which on reflection I think was probably unnecessary. As you say it's very twitchy between nil/low motion - the two could (should?) probably be treated as one.
|
Thread Tools | Search this Thread |
Display Modes | |
|
|