View Single Post
Old 20th January 2018, 23:58   #53  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
BELOW LINK UPDATE to TAKE_2 (RGB32 Alpha would contain rubbish, fixed, copies Alpha)
BELOW LINK UPDATE to TAKE_3 (Source fix in dprintf(), not used, No Change to Binary)

Here, FrameStore Plugin v0.0, fill your boots real.finder (Incl source, x86 only, ~12KB).
http://www.mediafire.com/file/4d74wl...120_TAKE_3.zip

FrameStore_ReadMe.txt
Code:
FrameStore(clip c)   # by StainlessS

An Avisynth v2.6, Filter to both take and produce a single frame.
All standard AVS v2.6 Colorspaces.

The function creates a store for FRAME 0 of the input clip c.
The function is intended to sever the link between a frame and any clips that it is reliant upon.



A=Colorbars.trim(0,-1)                                 # 1 frame
B=A.FlipVertical           # B is reliant upon clip A
C=A.Overlay(B,Opacity=0.5) # C is reliant upon clips A and B

D=C.FrameStore # D is not reliant upon A, or B, or C.

return D
SBX_MI.avs [Pagefile usage Flatlines at about 550MB on my test clip (The John Meyer parade Clip)].
EDIT: Above machine was newly set up from scratch, on another machine with much more stuff (software/codecs etc), it flatlines at about 620MB.
Code:
Function SBX_MI(clip c,int Factor, string "Mode", float "Opacity") {
/*
    Requires,
        RT_Stats, FrameStore (c) StainlessS.
        GSCript,Grunt, (c) Gavino.
*/
    c
    myName  = "SBX_MI: "
    Mode    = Default(Mode,"lighten")
    Opacity = Default(Opacity,1.0)
    Limit   = (Factor<=0) ? 1 : Max(1, FrameCount/Factor)
    FuncS="""
        Function Fn@@@(clip c,Int factor,String mode,Float opacity,Int limit) {
            n=current_frame
            if(Prev@@@ != n) {
                c
                cf=c.Trim(n,-1)                     # current frame
                if(Prev@@@ != n-1) {
                    Global B@@@ = cf                # First Frame OR User Jumping, Init/Reset to current frame
                } else {
                    # limit>1 ? Overlay(b.Loop(2,0,0),last,opacity=float(limit)/FrameCount) : b.Loop(2,0,0)
                    if(limit > 1) {
                        Global B@@@ = Overlay(B@@@,cf, opacity=float(limit)/FrameCount)
                    } # Else, B@@@ = Previous B@@@
                    # b.Overlay(last, mode=mode, opacity=opacity)

                    # REMOVE '.FrameStore' from end of next line to remove FrameStore and crash this function when out of memory.
                    Global B@@@=Overlay(B@@@,cf,mode=Mode,opacity=Opacity).FrameStore # Oops, removed .ChangeFps, prev attempt at fix

                }
                Global Prev@@@=n                    # REM for next time
            } # Else, Cache failure, repeat request for current frame, just return same as last time
            Return B@@@
        }
        #######################################
        # Unique Global Variables Initialization
        #######################################
        Global Prev@@@=-666
        #######################################
        # Unique Runtime Call, GScriptClip must be a one-liner:
        #######################################
        ARGS = "Factor,Mode,Opacity,Limit"
        c.GScriptClip("Fn@@@(last, "+ARGS+")", local=true, args=ARGS)
    """
    #######################################
    # Unique Identifier Definition
    #######################################
    GIFunc="SBX_MI"                    # 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)
    FrameCount!=1 ? GScript(InstS) : Last
    Return Last
}

AviSource("Parade.avi").trim(500,0)     # Some clip

SBX_MI(100)
EDIT:
Source.
Code:
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

//#define BUG                           // Uncomment to enable DPRINTF() output

// Version 0.0 FrameStore
/////////////////////////////////

#include "compiler.h"
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "avisynth.h"

#ifdef BUG
    int dprintf(char* fmt, ...) {
        char printString[2048]="FrameStore: ";
        char *p=printString;
        for(;*p++;);                                                 // These lines added in TAKE3
        --p;                                                            // @ null term
        va_list argp;
        va_start(argp, fmt);
        vsprintf(p, fmt, argp);
        va_end(argp);
        for(;*p++;);
        --p;                                                            // @ null term
        if(printString == p || p[-1] != '\n') {
            p[0]='\n';                                                  // append n/l if not there already
            p[1]='\0';
        }
        OutputDebugString(printString);
        return p-printString;                                           // strlen printString
    }
#endif

class FrameStore : public IClip {
private:
    const   VideoInfo vi;
    PVideoFrame frame;
    bool    parity;
    //
public:
    FrameStore(const VideoInfo& _vi,PVideoFrame _frame, bool _parity);
    ~FrameStore();
    void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {}
    const VideoInfo& __stdcall GetVideoInfo() { return vi; }
    bool __stdcall GetParity(int n) { return (vi.IsFieldBased() ? (n&1) : false) ^ parity; }
    int __stdcall SetCacheHints(int cachehints,int frame_range) {return 0;}
    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

FrameStore::FrameStore(const VideoInfo& _vi,PVideoFrame _frame, bool _parity)
        :  vi(_vi), frame(_frame), parity(_parity) {
    DPRINTF("Constructor: ENTER/EXIT")
}

FrameStore::~FrameStore() {
    DPRINTF("Destructor: ENTER/EXIT")
}

PVideoFrame __stdcall FrameStore::GetFrame(int n, IScriptEnvironment* env) {
    DPRINTF("GetFrame: ENTER on frame %d",n)
    n = 0; // Ignore frame and get frame 0
    DPRINTF("GetFrame: EXIT, returning Frame")
    return frame;
}

static AVSValue __cdecl Create_FrameStore(AVSValue args, void*, IScriptEnvironment* env) {
    DPRINTF("Create_FrameStore: ENTER")
    PClip child = args[0].AsClip();                               // clip compulsory arg
    const VideoInfo &InVi = child->GetVideoInfo();

    if(!(InVi.IsRGB24() || InVi.IsRGB32() || InVi.IsYUY2() || InVi.IsYV12() || InVi.IsYV16() || \
        InVi.IsYV24() || InVi.IsY8() || InVi.IsYV411()))
        env->ThrowError("FrameStore: Invalid Colorspace (standard AVS only)");
    if(!InVi.HasVideo() || InVi.num_frames<=0)
        env->ThrowError("FrameStore: No Video");
    //
    VideoInfo vi = InVi;
    bool parity = child->GetParity(0);
    //
    vi.audio_samples_per_second =0;     // 0 means no audio
    vi.sample_type              =0;     // as of 2.5
    vi.num_audio_samples        =0;     // changed as of 2.5
    vi.nchannels                =0;     // as of 2.5
    vi.num_frames               =1;
//
    PVideoFrame src    = child->GetFrame(0, env);
    const int rowsize  = src->GetRowSize(PLANAR_Y);         // PLANAR_Y no effect on RGB or YUY2
    const int pitch    = src->GetPitch(PLANAR_Y);
    const int height   = src->GetHeight(PLANAR_Y);
    const BYTE * srcp  = src->GetReadPtr(PLANAR_Y);
    //
    PVideoFrame dst    = env->NewVideoFrame(vi);            // Create initial frame
    const int dpitch   = dst->GetPitch(PLANAR_Y);
    BYTE * dstp        = dst->GetWritePtr(PLANAR_Y);
    //
    DPRINTF("Create_FrameStore: Making Frame")
    int x,y;
    if(vi.IsPlanar()) {     // Planar
        for(y=height;--y>=0;) {
            for(x=rowsize;--x>=0;) {
                dstp[x] = srcp[x];
            }
            srcp += pitch;
            dstp += dpitch;
        }
        const int srowsizeUV = src->GetRowSize(PLANAR_U);
        if(srowsizeUV) {                                        // Not Y8
            const int spitchUV  = src->GetPitch(PLANAR_U);
            const int sheightUV = src->GetHeight(PLANAR_U);
            const BYTE * srcpU  = src->GetReadPtr(PLANAR_U);
            const BYTE * srcpV  = src->GetReadPtr(PLANAR_V);
            //
            const int dpitchUV  = dst->GetPitch(PLANAR_U);
            BYTE * dstpU        = dst->GetWritePtr(PLANAR_U);
            BYTE * dstpV        = dst->GetWritePtr(PLANAR_V);
            //
            for(y=sheightUV;--y>=0;) {
                for(x=srowsizeUV;--x>=0;) {
                    dstpU[x] = srcpU[x];
                    dstpV[x] = srcpV[x];
                }
                srcpU += spitchUV;
                srcpV += spitchUV;
                dstpU += dpitchUV;
                dstpV += dpitchUV;
            }
        }
    } else if(vi.IsYUY2()) {    // YUY2
        for(y=height;--y>=0;) {
            for(x=rowsize;(x-=4)>=0;) {
                dstp[x + 0] = srcp[x + 0];
                dstp[x + 1] = srcp[x + 1];
                dstp[x + 2] = srcp[x + 2];
                dstp[x + 3] = srcp[x + 3];
            }
            srcp += pitch;
            dstp += dpitch;
        }
    } else {        // RGB
        if(vi.IsRGB24()) {
            for(y=height;--y>=0;) {
                for(x=rowsize;(x-=3)>=0;) {
                    dstp[x + 0] = srcp[x + 0];
                    dstp[x + 1] = srcp[x + 1];
                    dstp[x + 2] = srcp[x + 2];
                }
                srcp += pitch;
                dstp += dpitch;
            }
        } else {
            for(y=height;--y>=0;) {
                for(x=rowsize;(x-=4)>=0;) {
                    dstp[x + 0] = srcp[x + 0];
                    dstp[x + 1] = srcp[x + 1];
                    dstp[x + 2] = srcp[x + 2];
                    dstp[x + 3] = srcp[x + 3];     // Added in TAKE_2, Copy Alpha
                }
                srcp += pitch;
                dstp += dpitch;
            }
        }
    }
    DPRINTF("Create_FrameStore: Calling Constructor")
    AVSValue ret = new FrameStore(vi,dst, parity);
    DPRINTF("Create_FrameStore: returning Framestore filter. EXIT OK")
    return ret;
}


/* New 2.6 requirement!!! */
// Declare and initialise server pointers static storage.
const AVS_Linkage *AVS_linkage = 0;
/* New 2.6 requirement!!! */
// DLL entry point called from LoadPlugin() to setup a user plugin.
extern "C" __declspec(dllexport) const char* __stdcall
    AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
    /* New 2.6 requirment!!! */
    // Save the server pointers.
    AVS_linkage = vectors;
    DPRINTF("AvisynthPluginInit3: Adding FrameStore plugin")
    env->AddFunction("FrameStore", "c", Create_FrameStore, 0);
    DPRINTF("AvisynthPluginInit3: FrameStore plugin Added, Returning to Avisynth")
    return "`FrameStore' FrameStore plugin";
    // A freeform name of the plugin.
}
EDIT: FrameStore produces NO audio.
EDIT: Arh damn, spotted bug in RGB32, Alpha will hold rubbish, I'll up a another zip in a moment. (HAVE FIXED LINK)
EDIT: TAKE_3, Source fix in unused dprintf(), no change to binary. zip updated.
EDIT: Somebody wanna test it in AVS+ ? (standard v2.6 colorspaces)
EDIT: Real.Finder, any preference, Copy/Nullify Alpha of RGB32 ? (I used Copy, seemed more sensible for frame storage).

EDIT: Here a frame from my test script (Not the best choice of clip, it dont stay on scene for more than about 2 secs)
SBX_MI(10,"lighten",0.5)
__________________
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; 25th November 2018 at 13:33.
StainlessS is offline   Reply With Quote