View Single Post
Old 21st January 2018, 23:46   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Required RT_Stats v2.0 Beta(latest). [For RT_DBaseReadCSV() & RT_DBaseFindSeq()]
Here:- https://forum.doom9.org/showthread.p...26#post1818026

Steps:-
Create CSV txt file.
Make DBase via Make_DBase.avs
Use FredDB.Avs

Make_DBase.avs
Code:
# Make_DBase.avs
#########################
CSV="Fred_CSV.Txt"      # CSV.txt file containing text something like this
### Three Fields in DBase: Field 0=StartFrame, 1=EndFrame, 2=Value
# 100,200,50   # EDIT: Without the comments, of course
# 400,500,60
# 700,750,70
# 900,999,80
###
DB            = "Fred_CSV.DB"
TypeString    = "iii"              # 3 DB Fields, all type Int, Same as in CSV file above. (b=BOOL,i=INT,f=FLOAT,s=STRING,n=BIN(8bit Int).
###
CSV=RT_GetFullPathName(CSV)
DB=RT_GetFullPathName(DB)
RT_DBaseAlloc(DB,0,TypeString)     # Allocate DBase with 0 pre-allocated records, three Int Fields.
###
Added=RT_DBaseReadCSV(DB,CSV)
#RT_DBaseQuickSort(DB,Field2=1)   # Un-Comment if Ranges NOT in sorted order.
Return MessageClip("Added "+String(Added)+" Records")   # Shows "Added 4 Records where same as above Fred_CSV.Txt Example".
FredDB.Avs
Code:
# FredDB.Avs : Required RT_Stats v2.0 Beta(latest). [For RT_DBaseReadCSV() & RT_DBaseFindSeq()]
GScript("""
    Function FredFun(clip c,String DB,Int Default_Val,Int ValMax,Bool Show) {
        myName="FredFun: "
        c
        n           = current_frame
        Records     = RT_DBaseRecords(DB)   # Number of records in the DBase
        Start_Field = 0                     # Field in DBase that holds Start Frame Int (as per CSV file).
        End_Field   = 1                     # Field in DBase that holds End Frame Int.
        Val_Field   = 2                     # Field in DBase that holds Fred Value (in this case is an Int as specified in DB TypeString).
        Find_Frame  = n                     # Frame Number to search for in DBase.
        Low         = 0                     # Default 0. Lowest record number to scan (likely almost always 0).
        High        = Records-1             # Highest record number to scan (likely almost always as default RT_DBaseRecords(DB)-1).

        FndRec=RT_DBaseFindSeq(DB,Start_Field,End_Field,Find_Frame,Low=Low,High=High)  # Search DBase for sequence holding current_frame n
        if(FndRec>=0) {
            UseVal = RT_DBaseGetField(DB, FndRec, Val_Field)    # Get the value set for this frame (third val in CSV file)
        } Else {                                                # Fndrec -1, Record containing current frame Not Found
            UseVal = Default_Val                                # Use the Default, ie range not set in CSV.
        }

        Assert(0 <= UseVal <= ValMax, RT_String("FredFun: 0 <= ValMax <= %d (%d)",ValMax,UseVal))  # UseVal Range 0 -> ValMax ONLY

        #
        # Do whatever you want here to add FredAverage based on UseVal
        #

        if(Show) {
            if(FndRec>=0) {
                SIZE  = Last.Height/10
                COLOR = $FF00FF
                Start = RT_DBaseGetField(DB, FndRec, Start_Field)       # Where this range starts
                End   = RT_DBaseGetField(DB, FndRec, End_Field)         # Where this range ends
                S=RT_String("%d:%d:%d,%d] Val = %d",n,FndRec,Start,End,UseVal)
            } Else {
                SIZE  = Last.Height/14
                COLOR = $FFFF00
                S=RT_String("%d] Val = %d",n,UseVal)
            }
            Subtitle(S,Align=5,y=Height/2,Size=SIZE,Text_Color=COLOR)
        }
        Return Last
    }
""")

#### CONFIG ####
FN          = "Parade.Avi"
DB          = "Fred_CSV.DB"
Default_Val = 34
SHOW        = True
VALMAX      = 100    # Default_Val and CSV entries must be 0 -> VALMAX range.
################
FN          = RT_GetFullPathName(FN)
DB          = RT_GetFullPathName(DB)
ARGS        = "DB,Default_Val,ValMax,Show"          # FredFun args, excluding clip c
AviSource(FN)
Last.GScriptClip("FredFun(last, "+ARGS+")", local=True, args=ARGS)
Return Last
I've made it a sort of lesson rather than do it for you, if you have probs, just say.

ClipClop could also be used if many similar values for the non default range, just like ChaosKing suggestion.

EDIT: Entries in CSV HAVE TO BE SEQUENTIAL, else could fail to find them.
EDIT: Added In BLUE.

EDIT: Further on CSV.
Code:
RT_DBaseReadCSV(String DB, String CSV, String "Separator"=",",String "StrDelimiter"="\"",Int "StartField"=0,Int "EndField"=last_field)

    This function will extract CSV values in text file, and append them as records to an appropriately formatted DBase file.

    DB,           FileName of an RT_Stats DBase file.
    CSV,          FileName of a text CSV (Comma Separated Value) file.
    Separator     Default "," ie comma separator (first character only, Chr()'s 0, 13, 10, and 34 [Double Quote] illegal).
                  Default Separator "," (Comma) is optional and so long as CSV values are SPACE/TAB separated will not produce an error
                  if separator is missing.
    StrDelimiter  Default = "\"" ie single character string Double Quote.
                  StrDelimiter (String Delimiter) can be multiple characters (empty string "" illegal, also cannot contain the Separator
                  character nor SPACE or TAB), Default is a Double Quote single character string.
                  CSV string values CANNOT contain StrDelimiter string, ie for default StrDelimiter, strings cannot contain a double
                  quote character string. So long as the StrDelimiter does not appear within any string, nearly any StrDelimiter can be
                  used, eg "@@@" is a 3 character StrDelimiter that you could use in place of double quote string delimiters, where the
                  string values could then contain a double quote character, in such a case you should enclosed CSV strings as in
                  @@@Some text that contains a " double quote.@@@.
                  NOTE, StrDelimiter IS case sensitive, so if using alphabetic characters they have to match exactly.

    StartField    Default = 0.
    EndField      Default = last field in DBase record (By default, all fields should be present in CSV file, else error).
                  Above StartField and EndField args allow setting of limited number of CONSECUTIVE fields within a record, the remaining
                  fields if any are set to NULL values, ie String all zero chars, bool = false, Float=0.0, int and bin=0.

    Function returns Int, the number of records added to the DBase.
    (Maximum line length in CSV text file is 64*1024 characters).

    Example:-
        CSV.txt file containing text something like this
        ###
            1  ,42.0 ,true , "Hello"        # I am a comment
            2  ,43.5 ,false, "Goodbye"
            $FF,3.142,TRUE , "Coconuts"     # So Am I
        ###
        Script:-
        DB  = "My.DB"
        CSV = "CSV.txt"
        RT_DBaseAlloc(DB,0,"ifbs32")        # Allocate DBase with 0 pre-allocated records, 4 fields, 0)=Int, 1)=Float, 2)=bool, 3=String(maxlen=32).
        Added=RT_DBaseReadCSV(DB,CSV)
        Return MessageClip("Added "+String(Added)+" Records")   # Shows "Added 3 Records".
RT_DBaseFindSeq
Code:
RT_DBaseFindSeq(String DB,Int S_Field,Int E_Field,Int Frame,Int "Low"=0,Int "High"=RT_DBaseRecords(DB)-1)

 RT_DBaseFindSeq Returns clip (or record) number containing movie frame Frame, using Binary Search.

   DB,      DBase FileName,
   S_Field, DB field that contains the first frame of the record clip/sequence (within entire movie).
   E_Field, DB field that contains the Last frame of the record clip/sequence (within entire movie).
   Low,     Default 0. Lowest record number to scan (likely almost always 0).
   High,    Default RT_DBaseRecords(DB)-1. Hightest record number to scan (likely almost always as default).

   Return of -1 = RECORD NOT FOUND.

   eg If you have 4 clips in DBase, each of 10 frames then fields should contain data EXACTLY as below (must be ordered).
      Record     S_Field   E_Field
         0           0        9
         1          10       19
         2          20       29
         3          30       39
EDIT: ClipClop, or RemaplFramesSimple would be faster (than Scriptclip), but not as much fun EDIT: RT_DBaseFindSeq() is real fast.
Above stuff could easily be extended for other uses and/or additional variables (DBase supports up to 1024 Fields).

EDIT:
Quote:
ClipClop could also be used if many similar values for the non default range.
ClipClop(), is also used by FrameSurgeon() / SawBones combo.
Say you had 7 non default values,
create 7 clips, where, FX1-Fx7 use non default values in creating each clip [EDIT: FredAverage GamMac clips].
Using ClipClop via FrameSurgeon (supplying to FrameSurgeon, src=DefaultValueClip, + FX1->FX7),
create a 3x3 stack of 9 clips, src=DefaultValueClip, + FX1->FX7, + FrameSurgeon result frames.
Use Sawbones to view 3x3 stack and select and mark required FXn ranges, create FrameSurgeon frames file.
Run FrameSurgon for real with FINAL=True (source [in this case DefaultValueClip] is the default if not frame assigned as FXn).
Sorted.

DO NOT USE INTERPOLATED or other non Fx edits in SawBones, it would interpolate from DefaultValueClip. (Unless that is what you want).
If you only had 6 non defaults, then could also SHOW ONLY the real source frames in 3x3 stack.
If you have a real big monitor, could use DefaultValueClip + FX1 -> FX9 + real source + result in 3x4 or 4x3 stack.

EDIT: You feed the 3x3 stack into Sawbones (well, VirtualDubFilterMod when using SawBones), so you can select from avalable FX clips,
and view result when Save & Refresh key pressed.

EDIT: This one(SawBones):- https://forum.doom9.org/showthread.p...40#post1829340
__________________
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; 23rd January 2018 at 06:06.
StainlessS is offline   Reply With Quote