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. |
2nd June 2017, 16:59 | #2 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,695
|
That sounds like an odd production decision. I'm not saying it isn't so, but I am saying that it sure doesn't make sense. Please post a sample.
I did develop a script for finding gaps (missing frames) in video, and it works to some degree. However, even with strong motion in the video, it is rather difficult to reliably detect a missing frame. I posted it here in this forum many years ago. You won't want to use the part of the script that finds the duplicates, but the gap detection may be of some use: Automatically fix dups followed (eventually) by drops You will also find a link in my first post in that thread which goes to a thread where the OP was trying to solve the problem of a video that had been decimated from 30 to 24 fps. Sound familiar? In case you don't want to find that link, here it is: Inverse of Decimate |
3rd June 2017, 00:22 | #4 | Link |
Registered User
Join Date: Sep 2007
Posts: 5,377
|
If the cadence is constant , you can interpolate by inserting frames at the set interval, and replacing that with mvtools interpolated frame . The potential problem is if there was an edit post production (after the decimation), which can screw up the cadence and the results will be off - then you would need some procedural script with detection
eg just adjust the period and offset https://forum.videohelp.com/threads/...on#post2222196 For your clip, if you trim(2,0) to delete the first few frames (duplicates), it would be 5,3 Code:
orig=FFVideoSource("00003-002.mkv").trim(2,0) # Make a black clip, the same characteristics as your source BlankClip(Orig) Black=last # Insert black frame in those missing frames (just temporary placeholder, will replace later) Orig InterleaveEvery(Black, 5,3) BlackInserted=last # Generates Missing Frames by interpolation BlackInserted sup = MSuper() bv = MAnalyse(sup, isb=true, delta=2) fv = MAnalyse(sup, isb=false, delta=2) interpolated = MFlowInter(sup, bv, fv, time=50.0, ml=100).DuplicateFrame(0) replace = interpolated.SelectEvery(5,3) # Delete Black Frames DeleteEvery(5,3) # Replace Deleted Frames With Interpolated Frames InterleaveEvery(replace, 5,3) It's "smoother", but you're left with the ugly interpolation artifacts; very bad in some frames. You can try tweaking some of the mvtools2 settings to get slighty better results |
3rd June 2017, 13:48 | #7 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,695
|
I finally had a chance to look at the clip. It presents an impossible situation with all of those one-frame laser flashes and strobe lights. Motion estimation doesn't stand a chance. I think you'd get better results, at least on this clip, using simple frame blending, in place of the motion estimation.
|
3rd June 2017, 13:58 | #8 | Link |
Registered User
Join Date: May 2006
Posts: 3,997
|
You may also want to try out MysteryX's FrameRateConverter:
https://forum.doom9.org/showpost.php...&postcount=405 Edit: Out of curiosity I will run an encode with "slower" setting and upload the result when it's done ..... encoding at 0.07fps ...... Edit2: Here is what I got. The top left picture is made with ConvertFPS("ntsc_video") for comparison. http://www.mediafire.com/file/ph6dr2...RC_kuchi_b.mkv Last edited by Sharc; 3rd June 2017 at 16:08. |
4th June 2017, 15:22 | #9 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
For constant cadence,
(every 5th frame of original source missing, eg 29.97 decimated to 23.976) Code:
Avisource("D:\00003-002.mkv.AVI") # EDIT: I converted to AVI first ORG=Last # ADDED CONVFPS=true # True= ConvertFPS [ie blend], # False DoubleRate [from:- http://forum.doom9.org/showthread.ph...61#post1789461 ] # Any DoubleRate Interpolator could be substituted SEL = 2 # 0 -> 3 # EDIT: Position to blend/interpolate (0 interpolates 0<->1, 1 interp 1<->2 etc) # CONVFPS==FALSE, DoubleRate() Settings FLOW=True BLKSZ=32 OLAP=16 (CONVFPS) \ ? ConvertFPS(FrameRate*2.0) \ : DoubleRate(Flow=FLOW,Blksize=BLKSZ,Overlap=OLAP) # EDIT: Changed # E0=SelectEvery(8,0) O0=SelectEvery(8,1) # E1=SelectEvery(8,2) O1=SelectEvery(8,3) # E2=SelectEvery(8,4) O2=SelectEvery(8,5) # E3=SelectEvery(8,6) O3=SelectEvery(8,7) # EDIT: Just incase substitute DoubleRate() does not keep exact same EVEN input frames. (ConvertFPS and Linked DoubleRate do). E0=ORG.SelectEvery(4,0) O0=SelectEvery(8,1) E1=ORG.SelectEvery(4,1) O1=SelectEvery(8,3) E2=ORG.SelectEvery(4,2) O2=SelectEvery(8,5) E3=ORG.SelectEvery(4,3) O3=SelectEvery(8,7) Return Select(SEL,Interleave(E0,O0,E1,E2,E3),Interleave(E0,E1,O1,E2,E3),Interleave(E0,E1,E2,O2,E3),Interleave(E0,E1,E2,E3,O3)) EDIT: I think for your sample clip @ that start position, SEL should be 2 (greatest YDifference to next frame, most of the time). EDIT: I/P 23.976, O/P 29.97 FPS
__________________
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; 4th June 2017 at 17:34. |
4th June 2017, 17:09 | #10 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Script to select best SEL setting for constant cadence clip,
(every 5th frame of original source missing, eg 29.97 decimated to 23.976) Code:
# Show Best SEL Avisource("D:\00003-002.mkv.AVI") # Below dont need to be GLOBAL when at main script level (only if in function) G_Cnt0 =0 G_Cnt1 =0 G_Cnt2 =0 G_Cnt3 =0 SSS=""" n=current_frame m=n%4 ms=n/4*4 m0=RT_YDifference(Last,n=ms+0,delta=1) m1=RT_YDifference(Last,n=ms+1,delta=1) m2=RT_YDifference(Last,n=ms+2,delta=1) m3=RT_YDifference(Last,n=ms+3,delta=1) mB=Max(m0,m1,m2,m3) B=(m0==mB)?0:(m1==mB)?1:(m2==mB)?2:3 G_Cnt0=(n==ms && B==0) ? G_Cnt0 + 1 : G_Cnt0 # If in function, Assignment to G_Cntx need to be eg Global G_Cnt0= etc G_Cnt1=(n==ms && B==1) ? G_Cnt1 + 1 : G_Cnt1 G_Cnt2=(n==ms && B==2) ? G_Cnt2 + 1 : G_Cnt2 G_Cnt3=(n==ms && B==3) ? G_Cnt3 + 1 : G_Cnt3 x=RT_YDifference(Last,n=n,delta=1) CntMx=Max(G_Cnt0,G_Cnt1,G_Cnt2,G_Cnt3) BstCnt=(CntMx==G_Cnt0)?0:(CntMx==G_Cnt1)?1:(CntMx==G_Cnt2)?2:3 c0=(BstCnt==0) ?"!":"-" c1=(BstCnt==1) ?"!":"-" c2=(BstCnt==2) ?"!":"-" c3=(BstCnt==3) ?"!":"-" return RT_Subtitle("%d:%d] Dif=%f BestSEL=%d BestDif[%d]=%f\n\a%sSelCnt0=%d\a- \a%sSelCnt1=%d\a- \a%sSelCnt2=%d\a- \a%sSelCnt3=%d", \ n,m,x,B,B,mB,c0,G_Cnt0,c1,G_Cnt1,c2,G_Cnt2,c3,G_Cnt3) """ ScriptClip(SSS)
__________________
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; 16th July 2017 at 02:11. |
4th June 2017, 17:55 | #11 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
NOT for OP clip.
Where 30FPS decimated to 25.0, ie every 6th frame of original source missing (have seen many of these). Check SEL setting Code:
# Show Best SEL, (every 6th frame of original source missing, eg 30.0 decimated to 25.0, or 29.97 to 24.975) Avisource("D:\00003-002.mkv.AVI") # Some file name, not for OP clip # Below dont need to be GLOBAL when at main script level (only if in function) G_Cnt0 =0 G_Cnt1 =0 G_Cnt2 =0 G_Cnt3 =0 G_Cnt4 =0 SSS=""" n=current_frame m=n%5 ms=n/5*5 m0=RT_YDifference(Last,n=ms+0,delta=1) m1=RT_YDifference(Last,n=ms+1,delta=1) m2=RT_YDifference(Last,n=ms+2,delta=1) m3=RT_YDifference(Last,n=ms+3,delta=1) m4=RT_YDifference(Last,n=ms+4,delta=1) mB=Max(m0,m1,m2,m3,m4) B=(m0==mB)?0:(m1==mB)?1:(m2==mB)?2:(m3==mB)?3:4 G_Cnt0=(n==ms && B==0) ? G_Cnt0 + 1 : G_Cnt0 # If in function, Assignment to G_Cntx need to be eg Global G_Cnt0= etc G_Cnt1=(n==ms && B==1) ? G_Cnt1 + 1 : G_Cnt1 G_Cnt2=(n==ms && B==2) ? G_Cnt2 + 1 : G_Cnt2 G_Cnt3=(n==ms && B==3) ? G_Cnt3 + 1 : G_Cnt3 G_Cnt4=(n==ms && B==4) ? G_Cnt4 + 1 : G_Cnt4 x=RT_YDifference(Last,n=n,delta=1) CntMx=Max(G_Cnt0,G_Cnt1,G_Cnt2,G_Cnt3,G_Cnt4) BstCnt=(CntMx==G_Cnt0)?0:(CntMx==G_Cnt1)?1:(CntMx==G_Cnt2)?2:(CntMx==G_Cnt3)?3:4 c0=(BstCnt==0) ?"!":"-" c1=(BstCnt==1) ?"!":"-" c2=(BstCnt==2) ?"!":"-" c3=(BstCnt==3) ?"!":"-" c4=(BstCnt==4) ?"!":"-" return RT_Subtitle("%d:%d] Dif=%f BestSEL=%d BestDif[%d]=%f\n\a%sSelCnt0=%d\a- " + \ "\a%sSelCnt1=%d\a- \a%sSelCnt2=%d\a- \a%sSelCnt3=%d\a- \a%sSelCnt3=%d", \ n,m,x,B,B,mB,c0,G_Cnt0,c1,G_Cnt1,c2,G_Cnt2,c3,G_Cnt3,c4,G_Cnt4) """ ScriptClip(SSS) Code:
# Every 6th frame of original source missing, eg 30.0 decimated to 25.0, or 29.97 to 24.975 Avisource("D:\00003-002.mkv.AVI") # Some file name, not for OP clip ORG=Last CONVFPS=true # True= ConvertFPS [ie blend], # False DoubleRate [from:- http://forum.doom9.org/showthread.ph...61#post1789461 ] # Any DoubleRate Interpolator could be substituted SEL = 0 # 0 -> 4 # Position to blend/interpolate (0 interpolates 0<->1, 1 interp 1<->2 etc) # CONVFPS==FALSE, DoubleRate() Settings FLOW=True BLKSZ=32 OLAP=16 (CONVFPS) \ ? ConvertFPS(FrameRate*2.0) \ : DoubleRate(Flow=FLOW,Blksize=BLKSZ,Overlap=OLAP) # EDIT: Just incase substitute DoubleRate() does not keep exact same EVEN input frames. E0=ORG.SelectEvery(5,0) O0=SelectEvery(10,1) E1=ORG.SelectEvery(5,1) O1=SelectEvery(10,3) E2=ORG.SelectEvery(5,2) O2=SelectEvery(10,5) E3=ORG.SelectEvery(5,3) O3=SelectEvery(10,7) E4=ORG.SelectEvery(5,4) O4=SelectEvery(10,9) Return Select(SEL,Interleave(E0,O0,E1,E2,E3,E4),Interleave(E0,E1,O1,E2,E3,E4),Interleave(E0,E1,E2,O2,E3,E4), \ Interleave(E0,E1,E2,E3,O3,E4),Interleave(E0,E1,E2,E3,E4,O4))
__________________
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; 4th June 2017 at 19:45. Reason: Updated, a bit. |
5th June 2017, 05:09 | #12 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
PART_1, Post 1 of 2
Code:
# FindRepairCycleOffset.avs Function FindRepairCycleOffset(clip c,Int "OutCycle",Float "PassPerc",String "ARR",Bool "Verbose",Int "MaxAcross") { /* FindRepairCycleOffset(), By StainlessS @ Doom9, http://forum.doom9.org/showthread.php?p=1808723#post1808723 Colorspace, v2.6 Planar, YUY2, RGB. Requires:- RT_Stats, CallCmd, GScript, Grunt. Shows RepairCycle() required Offset arg for constant cadence clip where 1 frame in every OutCycle frames of original source was omitted from botched clip c. If start of clip is trimmed afterwards, then needs to be redone (or recalculated), before calling RepairCycle(), unless FramesTrimmed % (OutCycle-1) == 0 (ie trimmed by complete InCycles). If you jump forward, then display will cease whilst ALL frames up to jump frame are sampled and results added to an array, can jump backwards OK as all frames up to current frame are already in array. If you wish, you can call eg FindRepairCycleOffset().Trim(FrameCount-1,-1), ie trim off last frame only, and this will produce the final result frame with all frames sampled, and also is the fastest possible way as no frames are displayed before final result. A count array (CNT[InCycle]) is established of size InCycle. Each frame is differenced with the frame following using Luma RT_YDifference() and the element within the CNT[] array representing the frame with greatest difference within a Cycle, is incremented. When sufficient cycles have been sampled, the CNT[] element with greatest value is more likely to indicate the position within the cycle where the original source frames were omitted. (Anyway, thats the theory, but needs lots of samples/cycles to be of any use, the best and only real result is on the very last frame, any metrics prior to the last frame are based only on the data available up to that point in the clip). Args:- c, Botched input clip. OutCycle, Default 5, (3 <= OutCycle <= 1001), original source clip cycle, one frame of which was ommited from Botched input clip c. The only real reason for limiting OutCycle to 1001, is that there are only 1024 User Attributes in an RT_Stats array, so the number of items in returned user array attributes is also limited (hopefully this is enough for anyone, shout if not). eg Outcycle = 5, InCycle=4 (Outcycle-1) every 5th frame of original source missing, eg 30.0 was decimated to 24.0, or 29.97 to 23.976. eg Outcycle = 6, InCycle=5 (Outcycle-1) every 6th frame of original source missing, eg 30.0 was decimated to 25.0, or 29.97 to 24.975. Original Rate = c.FrameRate * OutCycle / InCycle PassPerc, Default (200.0/InCycle)%, (0.0 <= PassPerc < 100.0.). Greatest Cnt[OffSet] has to be greater or equal to this percentage of CyclesProcessedSoFar, to be considered 'conclusive' (0.0 = accept any result as conclusive). ARR, Default "" (not user supplied). Filename of User RT_Stats Array. If Not supplied, then temp Array will be created and will be auto deleted upon clip closure. If User Supplied, then will use supplied filename and return with resultant Array existing. Suggest name something like 'ARR=RT_GetFullPathName("~TMP"+RT_LocalTimeString(File=True)+".ARR")'. On Last frame and valid result >= PassPerc, then will set Array attributes as return result to client script, where array attributes are set:- Attrib[0] = Int, 1, if completed OK, 0 = Invalid Attribute results (Not >= PassPerc). Attrib[1] = Int, RESULT:- Offset (The Cycle offset RESULT of function) Attrib[2] = Int, InCycle (OutCycle = InCycle + 1) Attrib[3] = Int, TotalCycles in clip Attrib[4] = Int, CNT[Offset], Count of cycles where result Offset frame greatest dif to next. Attrib[5] = Float, Percentage of cycles where CNT[Offset] was greatest. Attrib[6+i] = Int, CNT[i] where i = 0 -> InCycle - 1. Can retrieve Array attributes via eg, 'OK = RT_ArrayGetAttrib(ARR,0) == 1' # Are Attributes Valid ? Verbose, Default True. Show Count Array on frame. MaxAcross, Default 10. Max width of Cnt[] array displayed on frame (when Verbose=True), if would screen wrap. Shows Metrics as below when OutCycle==5 (InCycle=OutCycle-1, and MaxIndex of Cnt[MaxIndex]=InCycle-1): "230:2 Flgs: SC? Cnt[2]=40" <- Current_frame, local cycle offset, Flags, and Maximum Cnt[Offset]=Value. "Dif=0.000 : BigDif[1]=16.787" <- YDifference Current_Frame<->Current_Frame+1, Greatest diff within current cycle. "Cnt[0]=05 Cnt[1]=06 Cnt[2]=40 Cnt[3]=07" <- The HiLited Cnt[2] is the global result Offset, on last frame. (Verbose=True, MaxWidth) "Cycle=58/58 : CompletedTo=230/230" <- Clip Progress, by Cycle, by FrameNo. "PassPerc=50.0% : 40=68.97%" <- Goodness so far. "Offset=2" <- The result, ie as above; highest Cnt[2]=40 and '?' NOT hilited. Where:- '230' is current frame number. "2"=Zero relative InCycle index of current frame(0->InCycle-1). Flgs: "S" If HiLited, then current frame within InCycle has greatest difference to following frame (current InCycle metric). "C" If HiLited, then current frame within InCycle Index has greatest count so far. Ideally, S and C flags should be HiLited BOTH TOGETHER, once every InCycle (OutCycle-1) frames. "?" If HiLited, then result is inconclusive, ie hilited Cnt[CycleIndex] as a percentage (of CyclesSoFar) is not >= PassPerc. CurDif='0.000', Difference between current_frame (as above '230') and next (frame 230 is last frame so dif to next = 0.0). BigDif[1]="16.787", Greatest Difference in current Cycle is at Cycle offset 1. Cnt[CycleIndex]=nnn, where CycleIndex in range 0->InCycle-1, and 'nnn' is count of cycles where CycleIndex had max dif to next frame (within scanned cycles so far). The Cnt[CycleIndex] with highest count (ie above Cnt[2]=40), will be hilted, ie is the FINAL result on Last frame of input clip. Offset="2", the final result on last frame when '?' flag NOT HiLited. */ myName="FindRepairCycleOffset: " OutCycle=Default(OutCycle,5) PassPerc = Default(PassPerc,200.0/(OutCycle-1)) Verbose=Default(Verbose,True) MaxAcross=Default(MaxAcross,10) ARR=Default(ARR,"") # Default, auto delete temp array file on clip closure. UserARR = ARR!="" Assert(RT_FunctionExist("GScriptClip"),RT_String("%sEssential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337",myName)) Assert(RT_FunctionExist("GScript"),RT_String("%sEssential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846",myName)) Assert(RT_FunctionExist("CallCmd"),RT_String("%sEssential CallCmd plugin installed, http://forum.doom9.org/showthread.php?t=166063",myName)) Assert(0.0 <= PassPerc < 100.0,RT_String("%s0.0 <= PassPerc < 100.0(%f)",myName,PassPerc)) Assert(3 <= OutCycle <= 1001,RT_String("%s3 <= OutCycle(%d) <= 1001",myName,OutCycle)) InCycle=OutCycle-1 FuncS=""" Function Fn@@@(clip c,Int InCycle,String DARR,String CARR,String Fmt,String Fmt2,Bool Verbose) { c n=current_frame FC=c.FrameCount CompletedTo=CompletedTo@@@ if(n > CompletedTo) { CycleBase = CompletedTo + 1 CycleY = CycleBase/InCycle CycleEndBase = n/InCycle*InCycle cntMxIx = (CycleY ==0) ? 0 : RT_ArrayGet(CARR,CycleY-1,1) # If not first cycle, prev Hi ix for(CycleStartFrm = CycleBase, CycleEndBase, InCycle) { mxDf= -1.0 mxDfIx=0 for(i=0, InCycle-1) { FrameNo=CycleStartFrm+i df=Last.RT_YDifference(n=FrameNo,delta=1) (FrameNo<FC) ? RT_ArraySet(DARR,df,FrameNo) : NOP if(df>mxDf) { mxDF=df mxDfIx=i } # find max dif to next frame if(CycleY>0) { xix = 2+i RT_ArraySet(CARR,RT_ArrayGet(CARR,CycleY-1,xix),CycleY,xix) # Copy from Prev Cycle } } mxDfCnt = RT_ArrayGet(CARR,CycleY,2+mxDfIx) + 1 # Incr Count with greatest diff RT_ArraySet(CARR,mxDfCnt,CycleY,2+mxDfIx) # RT_ArraySet(CARR,mxDfIx ,CycleY,0) # And store mxDfIx if(mxDfIx != cntMxIx) { # was not current greatest cnt, is it better ? cntMx = RT_ArrayGet(CARR,CycleY,2+cntMxIx) if(mxDfCnt >= cntMx) { # If equal, then mxDf was greater cntMxIx=mxDfIx # and the newly overtaking mxDfcnt } } RT_ArraySet(CARR,cntMxIx,CycleY,1) CycleY=CycleY+1 } CompletedTo = CycleStartFrm-1 Global CompletedTo@@@ = CompletedTo } CycleY = n / InCycle CyclesAtN = CycleY + 1 CycleStartFrm = CycleY * InCycle if(n==FC-1) { cntMxIx = RT_ArrayGet(CARR,CycleY,1) cntMx = RT_ArrayGet(CARR,CycleY,2+cntMxIx) if(cntMx>=CyclesAtN*PassPerc@@@) { if(RT_ArrayGetAttrib(CARR,0)==0) { # Not yet set completed flag myname="Fn@@@_DBUG: " Tim = RT_TimerHP-TImerStart@@@ RT_DebugF("Scan Time = %f secs %fFPS",Tim,FC/Tim,name=myName) RT_DebugF("CntMax(%d) = %6.3f%% of TotalCycles(%d)",cntMx,cntMx*100.0/CyclesAtN,CyclesAtN,name=myName) RT_DebugF("Setting Attributes",name=myName) RT_ArraySetAttrib(CARR,0,1) # Attrib[0]=COMPLETED OK, Attribute Results ARE VALID (DO NOT SET A SECOND TIME). RT_DebugF(" Attrib[0]=1 # VALID", name=myName) RT_ArraySetAttrib(CARR,1,cntMxIx) # Attrib[1]=RESULT:- Offset (The Cycle offset RESULT of function) RT_DebugF(" Attrib[1]=%-3d # Offset (Result)",cntMxIx,name=myName) RT_ArraySetAttrib(CARR,2,InCycle) # Attrib[2]=InCycle (OutCycle = InCycle + 1) RT_DebugF(" Attrib[2]=%-3d # InCycle (OutCycle=%d)",InCycle,InCycle+1,name=myName) RT_ArraySetAttrib(CARR,3,CyclesAtN) # Attrib[4]=Cnt[Offset], Cnt of cycles where result Offset frame greatest dif to next. RT_DebugF(" Attrib[3]=%-6d # TotalCycles in clip",CyclesAtN,name=myName) cnt=RT_ArrayGet(CARR,CycleY,2+cntMxIx) RT_ArraySetAttrib(CARR,4,cnt) # Attrib[4]=Cnt[Offset], Cnt of cycles where result Offset frame greatest dif to next. RT_DebugF(" Attrib[4]=%-5d # Cnt[Offset]",cnt,name=myName) GotPerc=cntMx*100.0/CyclesAtN RT_ArraySetAttrib(CARR,5,GotPerc) # Attrib[5]=GotPerc RT_DebugF(" Attrib[5]=%.3f # Percent gotten",GotPerc,name=myName) for(i=0,InCycle-1) { cnt=RT_ArrayGet(CARR,CycleY,2+i) RT_ArraySetAttrib(CARR,6+i,cnt) # Attrib[6+i] = Cnt[i] RT_DebugF(" Attrib[6+%d]=%-4d # Cnt[%d]",i,cnt,i,name=myName) } } } }
__________________
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; 10th June 2017 at 18:19. Reason: OOps, cocked up post, some script was missing |
10th June 2017, 02:17 | #13 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
PART_2, post 2 of 2
Code:
mxDfIx = RT_ArrayGet(CARR,CycleY,0) cntMxIx = RT_ArrayGet(CARR,CycleY,1) cntMx = RT_ArrayGet(CARR,CycleY,2+cntMxIx) curDf = RT_ArrayGet(DARR,n) BigDf = RT_ArrayGet(DARR,CycleStartFrm+mxDfIx) HILITE = 33 # RT_Ord("!") LOLITE = 76 # RT_Ord("L") WHITE = 45 # RT_Ord("-") xc=XCnts@@@ ixL=XCntIxLen@@@ cL=XCntLen@@@ S="" if(Verbose) { for(i=0,InCycle-1) { cnt=RT_ArrayGet(CARR,CycleY,2+i) Startcol=i==cntMxIx?HILITE:WHITE Midcol =(Startcol==WHITE&&i==mxDfix)?HILITE:Startcol S=S+RT_string(Fmt2,Startcol,MidCol,ixL,i,Startcol,cL,cnt,(i%xc==xc-1||i==InCycle-1)?10:32) } } SF=(n-CycleStartFrm==mxDfIx) ? HILITE:LOLITE CF=(n-CycleStartFrm==cntMxIx) ? HILITE:LOLITE BF=(cntMx>=CyclesAtN*PassPerc@@@) ? LOLITE:HILITE RT_Subtitle(Fmt,n,n-CycleStartFrm,SF,CF,BF,ixL,cntMxIx,cL,RT_ArrayGet(CARR,CycleY,2+cntMxIx),curDf,mxDfIx,BigDf, \ S, \ CyclesAtN,TotalCycles@@@,CompletedTo>=FC-1?HILITE:WHITE,Min(CompletedTo,FC-1),FC-1, \ PassPerc@@@*100.0,cntMx,cntMx*100.0/CyclesAtN, \ BF==HILITE?"???":RT_String("%-3d",cntMxIx)) Return Last } Fmt = "%d:%-2d] Flgs: \a%cS\a%cC\a%c?\a- \a!Cnt[%0.*d]=%0.*d\a-\nCurDif=%-7.3f : BigDif[\a!%d\a-]=%-7.3f\n" + \ "%s" + \ "Cycles=%d/%d : \a%cCompletedTo=%d\a-/%d\n" + \ "PassPerc=%.2f%% : \a!%d\a-=%.2f%% \n" + \ "Offset=%s" Fmt2="\a%cCnt[\a%c%.*d\a%c]=%.*d\a-%c" Global XCntLen@@@ = Int(Log10(Float(c.FrameCount) / InCycle)+1) Global XCntIxLen@@@=Int(Log10(InCycle-1)+1) Global XCnts@@@=Min((c.Width-20)/((7+XCntIxLen@@@+XCntLen@@@)*10),MaxAcross) # 7 = len of "Cnt[]= ", 10=width of chars in pixels. Global TImerStart@@@ = RT_TimerHP Global CompletedTo@@@ = -1 Global PassPerc@@@ = PassPerc/100.0 Global TotalCycles@@@ = (c.FrameCount+InCycle-1)/InCycle TmpNam = "~TMP@@@"+RT_LocalTimeString(File=True) ARR = RT_GetFullPathName( UserARR ? ARR : TmpNam+".CARR") DARR = RT_GetFullPathName( TmpNam+".DARR") RT_ArrayAlloc(ARR ,Type=1,Dim1=TotalCycles@@@,Dim2=2+InCycle) # 2 dimensional Array of Int RT_ArrayAlloc(DARR,Type=2,Dim1=c.FrameCount) # 1 dimensional Array of Float ARGS = "InCycle,DARR,ARR,Fmt,Fmt2,Verbose" c.GScriptClip("Fn@@@(last, "+ARGS+")",local=true, args=ARGS,after_frame=true) CallCmd(Close="CMD /C del "+DARR, Hide=true) # Auto Delete TEMP Array on clip closure. !UserARR ? CallCmd(Close="CMD /C del "+ARR, Hide=true) : NOP # Auto Del non-user TEMP ARR on clip closure. Return Last """ GIFunc ="FindRepairCycleOffset" # Function Name, Supply unique name for your multi-instance function. GIName =GIFunc+"_InstanceNumber" # Name of the Instance number Global RT_IncrGlobal(GIName) # Increment Instance Global (init to 1 if not already exists) GID = GIFunc + "_" + String(Eval(GIName)) InstS = RT_StrReplace(FuncS,"@@@","_"+GID) # RT_WriteFile("DEBUG_"+GID+".TXT","%s",InstS) # UnComment to write each unique script function instance to log file Return GScript(InstS) } Code:
Avisource("D:\00003-002.mkv.AVI") FindRepairCycleOffset(OutCycle=5).Trim(Framecount-1,-1) # Return only with Last frame and showing final result. Return Crop(0,0,640,128) Code:
00000096 565.37261963 [3140] Fn_FindRepairCycleOffset_1_DBUG: Scan Time = 5.205181 secs 44.378864FPS 00000097 565.37280273 [3140] Fn_FindRepairCycleOffset_1_DBUG: CntMax(40) = 68.966% of TotalCycles(58) 00000098 565.37292480 [3140] Fn_FindRepairCycleOffset_1_DBUG: Setting Attributes 00000099 565.37335205 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[0]=1 # VALID 00000100 565.37371826 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[1]=2 # Offset (Result) 00000101 565.37414551 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[2]=4 # InCycle (OutCycle=5) 00000102 565.37457275 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[3]=58 # TotalCycles in clip 00000103 565.37512207 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[4]=40 # Cnt[Offset] 00000104 565.37548828 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[5]=68.966 # Percent gotten 00000105 565.37603760 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+0]=5 # Cnt[0] 00000106 565.37664795 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+1]=6 # Cnt[1] 00000107 565.37719727 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+2]=40 # Cnt[2] 00000108 565.37774658 [3140] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+3]=7 # Cnt[3] client 2 script (just to demo Verbose MaxAcross, not neally enough frames for OutCycle=30, nor is clip suitable) Code:
Avisource("F:\V\JurassicPark.AVI").trim(0,-10000) FindRepairCycleOffset(OutCycle=30,MaxAcross=5).Trim(Framecount-1,-1) # Return only with Last frame and showing final result. Return Crop(0,0,640,256) Works real good. EDIT: And just for good measure, heres the debug output Code:
00000006 51.55144119 [2692] Fn_FindRepairCycleOffset_1_DBUG: Scan Time = 47.423885 secs 210.864212FPS 00000007 51.55158234 [2692] Fn_FindRepairCycleOffset_1_DBUG: CntMax(35) = 10.145% of TotalCycles(345) 00000008 51.55171204 [2692] Fn_FindRepairCycleOffset_1_DBUG: Setting Attributes 00000009 51.55212021 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[0]=1 # VALID 00000010 51.55253220 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[1]=0 # Offset (Result) 00000011 51.55296326 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[2]=29 # InCycle (OutCycle=30) 00000012 51.55335999 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[3]=345 # TotalCycles in clip 00000013 51.55390167 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[4]=35 # Cnt[Offset] 00000014 51.55430222 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[5]=10.145 # Percent gotten 00000015 51.55485916 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+0]=35 # Cnt[0] 00000016 51.55540085 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+1]=16 # Cnt[1] 00000017 51.55594635 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+2]=16 # Cnt[2] 00000018 51.55650711 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+3]=17 # Cnt[3] 00000019 51.55705261 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+4]=12 # Cnt[4] 00000020 51.55759811 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+5]=19 # Cnt[5] 00000021 51.55813980 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+6]=8 # Cnt[6] 00000022 51.55868912 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+7]=10 # Cnt[7] 00000023 51.55925369 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+8]=13 # Cnt[8] 00000024 51.55979919 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+9]=10 # Cnt[9] 00000025 51.56033707 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+10]=3 # Cnt[10] 00000026 51.56089020 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+11]=10 # Cnt[11] 00000027 51.56143570 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+12]=8 # Cnt[12] 00000028 51.56198120 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+13]=12 # Cnt[13] 00000029 51.56252289 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+14]=7 # Cnt[14] 00000030 51.56306839 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+15]=8 # Cnt[15] 00000031 51.56361008 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+16]=7 # Cnt[16] 00000032 51.56415939 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+17]=9 # Cnt[17] 00000033 51.56470871 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+18]=11 # Cnt[18] 00000034 51.56525040 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+19]=11 # Cnt[19] 00000035 51.56581497 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+20]=9 # Cnt[20] 00000036 51.56636047 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+21]=9 # Cnt[21] 00000037 51.56690598 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+22]=6 # Cnt[22] 00000038 51.56745148 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+23]=9 # Cnt[23] 00000039 51.56799316 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+24]=9 # Cnt[24] 00000040 51.56854248 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+25]=12 # Cnt[25] 00000041 51.56908798 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+26]=5 # Cnt[26] 00000042 51.56963348 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+27]=15 # Cnt[27] 00000043 51.57017899 [2692] Fn_FindRepairCycleOffset_1_DBUG: Attrib[6+28]=29 # Cnt[28] I'll have a go at RepairCycle() tomorrow.
__________________
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; 16th July 2017 at 02:09. |
10th June 2017, 17:25 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
RepairCycle.avs
Code:
Function RepairCycle(clip c,Int InCycle,Int Offset,String "RepairFunc",Bool "Show",Bool "Debug") { /* RepairCycle(), Interpolate frames where original source clip had decimated 1 frame in every InCycle+1 frames. Requires, RT_Stats, GScript, MvTools v2.0. (ColorSpace depends upon what MvTools supports, not RGB). c, Clip to fix. InCycle,Offset, A synthesized frame will be inserted following every c clip InCycle[Offset] frame. RepairFunc, Default "ConvertFPS(FrameRate*2.0)" # Default is Blended frames. or eg RepairFunc="DoubleRate(Flow=True,Blksize=32,Overlap=16)" # DoubleRate [from:- https://forum.doom9.org/showthread.php?p=1789461#post1789461] # Any DoubleRate Interpolator could be substituted */ c myName="RepairCycle: " Assert(RT_FunctionExist("GScript"),RT_String("%sEssential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846",myName)) Assert(RT_FunctionExist("MSuper"),RT_String("%sEssential MvTools v2.0 Installed",myName)) Assert(2 <= InCycle,RT_String("%s2 <= InCycle",myName)) Assert(0 <= Offset < InCycle,RT_String("%s0 <= Offset < InCycle",myName)) RepairFunc = Default(RepairFunc,"") RepairFunc = (RepairFunc=="") ? "ConvertFPS(FrameRate*2.0)" : RepairFunc Show=Default(Show,False) Debug=Default(Show,False) GSCript(""" COMMA=RT_Ord(",") SPACE=RT_Ord(" ") S = RT_String("Interleave(\n") for(i=0,InCycle-1) { S = S + RT_String("\\ c.SelectEvery(%d,%d)%c\n",InCycle,i,(i==offset||i!=InCycle-1)?COMMA:SPACE) If(i==Offset) { S = S + RT_String("\\ dr.SelectEvery(%d,%d)%c\n",InCycle*2,i*2+1,(i!=InCycle-1)?COMMA:SPACE) } } S = S + "\ )" (DEBUG) ? RT_DebugF("\nS='%s'",S,name=myName) : NOP """) dr = Eval("c."+RepairFunc) dr = (Show) ? dr.RT_Subtitle("Synthesized",Align=5) : dr Eval(S) Return Last } Code:
Import("FindRepairCycleOffset.avs") Import("RepairCycle.avs") # OP clip OUTCYCLE=5 SHOW=True OFFSET=2 DEBUG=True REPAIRFUNC="DoubleRate(Flow=True,Blksize=32,Overlap=16)" Avisource("D:\00003-002.mkv.AVI") RepairCycle(OUTCYCLE-1,OFFSET,Repairfunc=REPAIRFUNC,Show=SHOW) return last Code:
Import("FindRepairCycleOffset.avs") Import("RepairCycle.avs") OUTCYCLE=5 SHOW=True LEN=10000 OFFSET=2 # OutCycle[OFFSET+1] is missing DEBUG=True REPAIRFUNC="DoubleRate(Flow=True,Blksize=32,Overlap=16)" # Make test clip from JP PAL 25FPS. Avisource("F:\V\JurassicPark.AVI").trim(0,-LEN) # LEN frames test clip # Omit every forth frame (OutCycle[3] or following InCycle[OFFSET] ie following InCycle[2]) Interleave(SelectEvery(OUTCYCLE,0),SelectEvery(OUTCYCLE,1),SelectEvery(OUTCYCLE,2),SelectEvery(OUTCYCLE,4)) RepairCycle(OUTCYCLE-1,OFFSET,Repairfunc=REPAIRFUNC,Show=SHOW) Return Last Code:
Import("FindRepairCycleOffset.avs") Import("RepairCycle.avs") # Auto mode OUTCYCLE=5 SHOW=True LEN=10000 DEBUG=True REPAIRFUNC="DoubleRate(Flow=True,Blksize=32,Overlap=16)" # Make test clip from JP PAL 25FPS. Avisource("F:\V\JurassicPark.AVI").trim(0,-LEN) # LEN frames test clip # Omit every forth frame (OutCycle[3] or following InCycle[OFFSET] ie following InCycle[2]) Interleave(SelectEvery(OUTCYCLE,0),SelectEvery(OUTCYCLE,1),SelectEvery(OUTCYCLE,2),SelectEvery(OUTCYCLE,4)) # Find InCycle Offset. ARR=RT_GetFullPathName("~TMP"+RT_LocalTimeString(File=True)+".ARR") RESULTC=FindRepairCycleOffset(OutCycle=OUTCYCLE,ARR=ARR) RT_AverageLuma(RESULTC,n=Framecount-1) # Force Last frame to be fetched (otherwise not requested unless returning RESULTC for display) OK = RT_ArrayGetAttrib(ARR,0) == 1 # Are Attributes Valid ? Assert(OK,"Offset Not found") Offset=RT_ArrayGetAttrib(ARR,1) RepairCycle(OUTCYCLE-1,Offset,Repairfunc=REPAIRFUNC,Show=SHOW,Debug=DEBUG) RT_FileDelete(ARR) Return Last # Return auto repaired clip changed to all using RepairCycle, I hope.
__________________
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; 10th June 2017 at 18:30. |
14th October 2017, 15:47 | #16 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Did it produce acceptable results ?
I did scripts as a bit of a folly. When testing on Jurassic Park(PAL), I got the impression that the original was shot at much higher frame rate, and could (I think) tell where frames had been dropped from the higher rate. (I dont actually remember what I concluded, just that something did 'stick out' from results, could also see where cadence changed from scene to scene due to editing, seemed to be able to tell what it was before studio editing).
__________________
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 ??? |
14th October 2017, 18:17 | #17 | Link |
Registered User
Join Date: Oct 2014
Posts: 476
|
Yes, but oddly it seems to miss a frame now and again. It will just double the frame before the jump, and this may continue for a while. Is there some scene change detection, and a way to change the level if so?
Last edited by kuchikirukia; 14th October 2017 at 18:26. |
14th October 2017, 19:02 | #18 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
If cadence changes then is unlikely to be of use (not terribly useful anyway, as could fix by hand in such a case where constant cadence).
Detect on single scene would likely not create sufficiently useful results, needs lots of frames to be statistically significant. X-Men II has at least 1 scene/shot of a single frame. (not counting the jump about intro)
__________________
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 ??? |
|
|