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. |
|
|
Thread Tools | Search this Thread | Display Modes |
29th October 2021, 01:23 | #21 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
I'm definitely using his compile, but I'll have to wait until I'm back on the office computer to check the version number. I'm pretty sure I updated it to something fairly recent.
However, I still think the problem with the merge with white not producing an identical frame lies with the mt_merge plugin, not with MVTools2. I've been tied up with other things today, but during driving time I thought about this script and am slowly coming to the conclusion that as good as Didée's idea is, it may actually be at the heart of the problem. The issue is that you have to keep the video the same length, which his idea brilliantly handles. Put another way, for each drop you fill, you have to find a duplicate (or near duplicate) to delete. Dups removed must equal new frames added at drop points. I have really good detection logic (he said modestly) that finds both drops and dups. The trick of the whole thing is to have an approach which 100% guarantees that the number of drops filled exactly equals the number of dups removed. If the drops and dups are sparse, and if the Cycle size is large enough, this Didée'-inspired script is going to work most of the time, but if you have lots of drops and if the Cycle size is small, it will fail a lot. So, I am contemplating rethinking the whole idea and coming up with something that eliminates TDecimate from the script. Unfortunately, this is likely to lead to a convoluted workflow, where I export my dup and drop metrics, dump them into a spreadsheet, and then use spreadsheet formulas and VBA to come up with a list of dups and drops which I'll feed back into an AVISynth script. Unfortunately, I don't know if there is any plugin which will take such a list because I don't think you can just arbitrarily add a few frames here or subtract a few frames somewhere else. That isn't how AVISynth works. Anyway, I'm going to keep trying for a few more days. There needs to be a solution to this problem. |
29th October 2021, 03:10 | #22 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,990
|
I'm kinda reluctant to use Expr() for anything in my scripts directory, If I need to test something under 2.60 std, then I gotta remove all of those scripts so as not to cause multiple problems.
__________________
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 ??? |
29th October 2021, 17:48 | #23 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
Never was quite sure why you need to use a mask at all. Why can't you just get your drop seeking routine to choose between Source and a (single) MFlowInter interpolation clip? Interleave with Source and do your TDecimate.
|
29th October 2021, 18:48 | #24 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,990
|
Quote:
Quote:
so you dont get all of it when you want it all, and do get some of it when you want none. Nothing wrong with mt_merge, problem is in script [as pointed out (I think) by several people in several threads].
__________________
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 ??? Last edited by StainlessS; 29th October 2021 at 18:59. |
||
29th October 2021, 19:32 | #26 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
I have had the same question a few times as I've been working on this. Didée's code from the "Inverse of Decimate" thread used a mask to choose the clip. If I'd coded this from scratch I would have used ConditionalFilter, or something similar. Perhaps I will make that change now because it would make it simpler to get to the bottom of my problems if the exact dups created by doubling the number of rames source video would cause TDecimate to return a dup metric of 0.00. This would make it simpler to do the right thing with the "almost" dups in the actual video that need to be decimated.
|
29th October 2021, 19:33 | #27 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,990
|
Yep, he just wants to be popular, very needy, sad really.
__________________
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 ??? |
29th October 2021, 19:35 | #28 | Link | |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
Quote:
|
|
29th October 2021, 19:41 | #29 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,990
|
Code:
Levels(16,1.0,235,0,255,coring=false)
__________________
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 ??? |
31st October 2021, 13:17 | #31 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
Doesn't it just mean replacing MFlowfps with MFlowInter, Blackframe with Source, WhiteFrame with the MFlowInter clip, juggling the interleave and forgetting the merge_mt?
It seems to me there's no way to get round the cycle difficulty, and that the problem is intrinsic in the method, not down to TDecimate, which is just doing what it's paid for. Whatever method you use for removing the 50% of frames with the least change, it will have to be regional, otherwise (apart from the time taken!) sequences with lots of movement will inevitably steal frames from sequences with very little movement. Regions have boundaries and dupe/drop pairs will inevitably straddle those boundaries at times. You'd have to devise a very sophisticated algorithm which would seek to identify the dupe nearest to a drop and link the two in some way, marking the dupe so it's no longer available - not too hard in a normal programming environment but I suspect way outside the constraints imposed by Avisynth. Simplest perhaps to just repeat the whole procedure as necessary - lengthy perhaps, but getting rid of the mask must save a bit of time. It's a very fine script as it is. |
31st October 2021, 17:55 | #32 | Link | |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
Quote:
Which brings me to my current idea, but one which I can't quite figure out to do. Here it is. My next approach will be to export the drop matching metrics from my detection function and also export dup matching metrics, either from TDecimate or from my own matching logic. I'll then put those metrics into an Excel spreadsheet. In that sheet I can use a combination of formulas and VBA (much easier than coding a plugin in C), to look backwards and forwards to match the nearest dup with its corresponding drop and use those matches to create a column which shows at which frames a motion-estimated frame must be inserted, and also which frames must be decimated because they are dups. The logic will ensure that dups=drops. Then, in AVISynth, I'll create the intermediate frames by doubling the frame rate and then using SelectOdd() to choose only the intermediate frames. This will give me a stream from which I can insert frames to bridge the drop. However, this is where I hit a dead end. I need to have some way in which I can insert frames arbitrarily and can decimate frames arbitrarily. I don't think AVISynth provides a mechanism for this even though the total number of frames will, in the end, be the same. I can write a script in my NLE, Vegas Pro, that will take the original video along with the "in-between frames" stream (which is the same length as the original video, but shifted in time by half a frame) and perform the substitutions and decimation, but very few people reading this will be able to use such a thing because most people don't own Sony Vegas Pro. I know that I can do arbitrary decimation using MultiDecimate because I do that all the time with my shutterless projector film transfer system that I invented fifteen years ago and which I have posted about several times in this forum. However, while it can easily do arbitrary decimation from a list of frame numbers, I don't think it permits me to arbitrarily insert frames. So, bottom line, the approach I adopted from Didée years ago is fundamentally flawed, and I am now thinking that the way in which AVISynth works will make it impossible for me to do this task completely from within the AVISynth environment. To do so will require me to
I need to build up the desire to keep going on this. My head hurts right now from banging it against the wall. I may re-visit the idea Zorr had in your Dropped frames thread where I run TDecimate three times with Cycle, 2*Cycle, and 3*Cycle and then "vote" by using Median() to make the decision on decimation based on which two provides the same result. However, as I think through that, if there are lots of drops and dups, you get overlap between the drops and the dups, and the voting may get confused. Last edited by johnmeyer; 31st October 2021 at 18:12. |
|
31st October 2021, 19:51 | #33 | Link | |
Banana User
Join Date: Sep 2008
Posts: 1,008
|
Quote:
Code:
BlackFrame = BlankClip( source, Color_yuv=$000000, pixel_type="Y8" ) WhiteFrame = BlankClip( source, Color_yuv=$FFFFFF, pixel_type="Y8" )
__________________
InpaintDelogo, DoomDelogo, JerkyWEB Fixer, Standalone Faster-Whisper - AI subtitling |
|
31st October 2021, 20:48 | #34 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
The writer of that script weren't no slouch.
I'm very inexperienced with Avisynth so be kind if I'm talking nonsense. If you export your data (how do you do this?) and can externally generate a text file that has a code for each frame (normal/delete/insert_after) that can be read by ConditionalReader, might it be possible to build up the output file in one pass? You would have to have at least one variable available from one frame to the next (is this possible?) which kept tabs on how out of step you were when choosing a frame (increment after delete, decrement after insert) from the clip (normal or interpolated) specified by the imported code. Something like Code normal__________selectevery(source,1,stepcode) delete__________increment stepcode; selectevery(source,1,stepcode) insert_after______decrement stepcode; selectevery(interp,1,stepcode) I've probably got the logic wrong but is the general idea viable? |
31st October 2021, 21:27 | #35 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
The key limitation of AVISynth is that it has to know, at every step in the script, the number of frames in the video file. You can use functions which, as an example, double the frames (like MFlowFPS), but I don't think there is a way to insert a frame here, and then a frame there, at arbitrary points.
|
1st November 2021, 01:31 | #36 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
Don't follow. The number of frames in the output is the same as the input and doesn't change. There's no insertion or deletion: each output frame is specified according to the algorithm based on information from the text file which your clever spreadsheet program has compiled.
It might look something like Code:
Outputfile=Scriptclip(source,"stepcode=stepcode+framecode"+ chr(13) + \ "framecode < 1 ? selectevery(source,1,stepcode) : selectevery(interp,1,stepcode)") ConditionalReader("spreadsheet.txt","framecode",false) Your spreadsheet text file would look something like Code:
Type Int Default 0 1 0 2 0 3 -1 4 0 5 1 etc And of course your spreadsheet would have to provide the text file in the right format.....with the right values! |
1st November 2021, 01:44 | #37 | Link |
Banana User
Join Date: Sep 2008
Posts: 1,008
|
Why you need Excel for dupe detection?
__________________
InpaintDelogo, DoomDelogo, JerkyWEB Fixer, Standalone Faster-Whisper - AI subtitling |
1st November 2021, 02:31 | #38 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,706
|
I don't need Excel for detection; AVISynth YDifference can do that quite well. What I need it for is to solve the problem of deciding which "dup" to delete.
Let me go back to the statement of the problem:
By putting the metrics into an Excel spreadsheet, the decimation can be done without using cycles. The idea is to start with the first drop and then scan the next "n" frames for a metric that indicates a dup, and mark that for deletion. That will take a little work, but I know I can do it because I've done something very similar before. What I don't know is how to use the metrics I create with the spreadsheet to reassemble the video in AVISynth, with motion estimated frames inserted at the drop points, and duplicates removed at the locations with identical frames. I can script it in Vegas Pro, but that won't help people here. I have a long plane ride at the end of the week and I may use that time to see how far I can get with this. However, I'm stuck at the moment doing it all with AVISynth until and unless I get a few hints or ideas. BTW, one reason I stuck with the original approach for so long is not only does it work for many drop/dup pairs, but also if the detection logic flags a "drop" that really isn't a drop, the visual penalty is very small. Any approach must gracefully handle false detection, given that perfect detection of every drop is not possible. Last edited by johnmeyer; 1st November 2021 at 02:36. |
1st November 2021, 17:14 | #39 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
There 'tis done. Finally cracked the diabolical ConditionalReader syntax (phew!)
Code:
source=AVISource( "D:\Video\wares-28-09-2021-17-35-08.avi" ).trim(5000,6000) stepcode=0 super = MSuper(source) backward_vectors = MAnalyse(super, isb = true, delta=1) forward_vectors = MAnalyse(super, isb = false, delta=1) interp = MFlowInter(source,super, backward_vectors, forward_vectors, time=50, ml=70).subtitle("**") final=Scriptclip(source,"stepcode=stepcode+framecode"+ chr(13) + \ "framecode < 1 ? selectevery(source,1,stepcode) : selectevery(interp,1,stepcode)") final2=ConditionalReader(final, "spreadsheet.txt", "framecode", true) return final2 With the text file example in my previous post, the output would be Frame 0=source frame 0, stepcode=0 Frame 1=source frame 1 Frame 2=source frame 2 Frame 3=interp frame 2, stepcode= -1 Frame 4=source frame 3, stepcode= -1 Frame 5=source frame 5, stepcode=0 etc (Must be reset with F2 if you fiddle with the timeline or the value of stepcode is corrupted) Last edited by stephen22; 1st November 2021 at 17:32. |
16th November 2021, 23:56 | #40 | Link |
Registered User
Join Date: Jan 2007
Posts: 88
|
That does work but only if dupes and drops are guaranteed to alternate, which doesn't usually happen. Better approach is to generate a text file which specifies the actual frame number required, indicating whether it's from the original clip or an interpolation. A good way of doing this is by by making interpolated frames negative, so 127 means frame 127 from the source clip and -127 means frame 127 from the interpolation clip.
So this is the method, based on John's brilliant insights - it works pretty well! 1. Generate a file of the ydiff data: the mfile from Multidecimate will do for this. Code:
loadplugin ("D:\Videos\Avisynth\plugins\MultiDecimate.dll") avisource ("D:\Video\SONY_DVD_RECORDER_VOLUME\ambass test.avi").converttoyuy2 multidecimate (pass=1) #***run video analysis pass then exit VD immediately*** 3. Put the file in the same folder as this avs script, and run the script. Code:
loadplugin("C:\program files (x86)\avisynth\plugins\mvtools2.dll") source=avisource ("D:\Video\SONY_DVD_RECORDER_VOLUME\ambass test.avi") source2=scriptclip(source,"subtitle (string(current_frame))") super = MSuper(source) backward_vectors = MAnalyse(super, isb = true, delta=1) forward_vectors = MAnalyse(super, isb = false, delta=1) interp = MFlowInter(source,super, backward_vectors, forward_vectors, time=50, ml=70).duplicateframe(0) interp2=scriptclip(interp,"subtitle (string(current_frame) + chr(42))") final=Scriptclip(source2,"step = (framecode>0)? framecode - current_frame : 0 - (framecode + current_frame)" + chr(13) + \ "framecode >= 0 ? selectevery(source2,1,step) : selectevery(interp2,1,step)") return stackvertical(ConditionalReader(final, "spreadsheet.txt", "framecode", true),source2) 1. Set thresholds for dupe, drop and scene change. 2. Divide the clip into scenes, which will be processed individually 3. In each scene, score each frame by comparing with the average of the 16 frames surrounding it. 4. Identify and mark the drops 5. For each drop, mark the first dupe among the 8 surrounding frames. If none is found, mark the frame which has the lowest score. 6. Build up the output file, adding frame numbers to the list sequentially starting from 0. If a frame is marked as a dupe, skip its frame number. Put in frames marked as drops twice, the first time negative (to specify an interpolated frame). Save as a text file, in the format required by ConditionalReader (frame number followed by data.) Here is a ragged clip captured by an HDMI to PAL converter, and the "spreadsheet" text file generated from its mfile data by my program. The Avisynth script above will display the clip before and after processing for comparison, with the frame number, aesterisked if interpolated, in the top left hand corner. https://drive.google.com/file/d/1kzy...ew?usp=sharing There's enormous scope here for skilful programming - for instance a sudden increase in movement within a scene can be a problem, creating runs of spurious "drops" which will in turn generate spurious "dupes" which will be removed and introduce new dropped frames. I thought I might try to identify this by comparing the 8 framescores before a frame with the 8 after, and perhaps starting a new "scene" if there is a large increase. It might also be useful to automatically adjust the dupe and drop thresholds for individual scenes according to the amount of movement. There's all sorts of problem-solving to be done. All of which is easy in a normal programming environment. Unfortunately my version is programmed on an ancient computer - the Atari ST (in fact an ST emulator for Windows called Steem.) If anybody's interested I could supply the necessary files to run the program, which I would have to make a bit more user-friendly. But maybe if there's sufficient interest and demand, programmers more skilful than I could write exe files that everyone could use easily. Last edited by stephen22; 17th November 2021 at 00:25. |
Tags |
drops, duplicates, tdecimate |
Thread Tools | Search this Thread |
Display Modes | |
|
|