Log in

View Full Version : ForceProcess v1.00 - 24 July 2018


StainlessS
24th July 2018, 15:27
ForceProcess(), v1.00, By StainlessS @ Doom9

A standalone drop in replacement for RT_Stats v2.0(currently Beta11) RT_ForceProcess().

EDIT: Almost the same as TWriteAVI v2.0 ForceProcessAVI.
TWriteAVI v2.0 is an incredibly useful plugin, but not likely to be released in x64 without someone else taking over project,
requires better CPP and ASM/Intrinsic programmer.
(I do not have the inclination to acquire further skills in either, this ol' dog don't wannt learn no new tricks)



ForceProcess(), v1.00, By StainlessS @ Doom9

Requires VS2008 CPP runtimes,

ForceProcess(clip, bool "Video"=True,bool "Audio"=false,Bool "Debug"=True) :- Returns 0


If Video (default true), Force read every frame of clip from 0 to FrameCount-1.
If Audio (default false), Force read every sample of clip from 0 to NumberOfSamples-1.
Useful where a clip outputs some kind of file for use in a second filter, this function would in such a case
forcibly read and therefore write the file, so that it may be available to other filters or to a second pass of the filter that
initially wrote the file.
Debug, default true. Write Progress to DebugView.

The ForceProcess function forcibly processes both video and audio streams (ie reads each frame/sample in sequence),
so that any eg log files produced by either video and/or audio processing filter will be forcibly written to disk.
ForceProcess is a runtime function not filter and so only returns on completion.

Example:

Two Pass:

WhateverSource(...)
A_Two_Pass_Function(Pass=1) # Create some kind of deshaker log or whatever.
ForceProcess() # Force Pass 1, creating log
A_Two_Pass_Function(Pass=2) # Use created log
return Last



Debug output looks something like this (See DebugView - https://docs.microsoft.com/en-us/sysinternals/downloads/debugview )

00000005 12:42:07.125 [3404] ForceProcess: Commencing Forced process
00000006 12:42:07.437 [3404] ForceProcess: 187] 4.98% nFrms=188 T=0.313sec : 600.64FpS 0.001665SpF
00000007 12:42:07.828 [3404] ForceProcess: 376] 9.99% nFrms=189 T=0.390sec : 484.62FpS 0.002063SpF
00000008 12:42:08.140 [3404] ForceProcess: 565] 14.99% nFrms=189 T=0.313sec : 603.83FpS 0.001656SpF
00000009 12:42:08.484 [3404] ForceProcess: 754] 20.00% nFrms=189 T=0.343sec : 551.02FpS 0.001815SpF
00000010 12:42:08.781 [3404] ForceProcess: 942] 24.98% nFrms=188 T=0.297sec : 633.00FpS 0.001580SpF
00000011 12:42:09.093 [3404] ForceProcess: 1131] 29.99% nFrms=189 T=0.313sec : 603.83FpS 0.001656SpF
00000012 12:42:09.437 [3404] ForceProcess: 1320] 34.99% nFrms=189 T=0.344sec : 549.42FpS 0.001820SpF
00000013 12:42:09.750 [3404] ForceProcess: 1509] 40.00% nFrms=189 T=0.312sec : 605.77FpS 0.001651SpF
00000014 12:42:10.093 [3404] ForceProcess: 1697] 44.98% nFrms=188 T=0.344sec : 546.51FpS 0.001830SpF
00000015 12:42:10.468 [3404] ForceProcess: 1886] 49.99% nFrms=189 T=0.375sec : 504.00FpS 0.001984SpF
00000016 12:42:10.875 [3404] ForceProcess: 2075] 54.99% nFrms=189 T=0.406sec : 465.52FpS 0.002148SpF
00000017 12:42:11.265 [3404] ForceProcess: 2264] 60.00% nFrms=189 T=0.391sec : 483.38FpS 0.002069SpF
00000018 12:42:11.625 [3404] ForceProcess: 2452] 64.98% nFrms=188 T=0.359sec : 523.68FpS 0.001910SpF
00000019 12:42:11.953 [3404] ForceProcess: 2641] 69.99% nFrms=189 T=0.328sec : 576.22FpS 0.001735SpF
00000020 12:42:12.250 [3404] ForceProcess: 2830] 74.99% nFrms=189 T=0.297sec : 636.36FpS 0.001571SpF
00000021 12:42:12.515 [3404] ForceProcess: 3019] 80.00% nFrms=189 T=0.266sec : 710.53FpS 0.001407SpF
00000022 12:42:12.781 [3404] ForceProcess: 3207] 84.98% nFrms=188 T=0.265sec : 709.43FpS 0.001410SpF
00000023 12:42:13.093 [3404] ForceProcess: 3396] 89.99% nFrms=189 T=0.313sec : 603.83FpS 0.001656SpF
00000024 12:42:13.453 [3404] ForceProcess: 3585] 94.99% nFrms=189 T=0.359sec : 526.46FpS 0.001899SpF
00000025 12:42:13.765 [3404] ForceProcess: 3774] 100.00% nFrms=189 T=0.313sec : 603.83FpS 0.001656SpF
00000026 12:42:13.765 [3404] ForceProcess: Time=6.641secs (0.111mins) : Avg 568.438FpS 0.001759SpF


dll's for Avisynth v2.58, avs/+ v2.60 x86 and x64, + source + VS2008 Project files. (~68KB)

See Mediafire OR SendSpace in my sig below this post.

StainlessS
24th July 2018, 15:28
Most of source


#include "compiler.h"
//
#include <windows.h>
#include <stdio.h>
#include <time.h>
//
#ifdef AVISYNTH_PLUGIN_25
#include "avisynth25.h"
#else
#include "avisynth.h"
#endif

int __cdecl dprintf(char* fmt, ...) {
char printString[2048]=""; // Must nul term, at least with eg "Test: " or ""
char *p=printString;
for(;*p++;);
--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 int(p-printString); // strlen printString
}

AVSValue __cdecl ForceProcess(AVSValue args, void* user_data, IScriptEnvironment* env) {
// Force read frames.
char *myName="ForceProcess: ";
if(!args[0].IsClip()) env->ThrowError("%sMust have a clip",myName);
PClip child = args[0].AsClip(); // Clip
const VideoInfo &vi = child->GetVideoInfo();
const int frames=vi.num_frames;
const bool video = (args[1].AsBool(true) && vi.HasVideo() && frames > 0);
const bool audio = (args[2].AsBool(false) && vi.HasAudio() && vi.num_audio_samples > 0);
const bool debug=args[3].AsBool(true);
const __int64 nsamples = (!audio) ? 0 : (video) ? vi.AudioSamplesFromFrames(1) : vi.audio_samples_per_second;
BYTE *bf = NULL;
if(audio) {
int bfsz = int(vi.BytesFromAudioSamples(nsamples));
bf = new BYTE[bfsz];
if(bf==NULL) env->ThrowError("%sCannot allocate audio buffer",myName);
}
if(video) {
double start_T = double(clock()) / double(CLOCKS_PER_SEC);
double sT = start_T;
int parts = min(20,frames);
int part=1;
int sf=0; // this time start frameno
int stopf = frames * part / parts;
if(debug) dprintf("%sCommencing Forced process",myName);
for(int n=0;n<frames;++n) {
if(bf!=NULL) {
__int64 s = vi.AudioSamplesFromFrames(n);
__int64 e = vi.AudioSamplesFromFrames(n+1);
child->GetAudio((void*)bf, s, e-s, env); // Force 1 video frame worth of audio
}
PVideoFrame src = child->GetFrame(n,env); // Force decoding. MUST assign to PVideoFrame
if(debug && n+1 >= stopf) {
double now = double(clock()) / double(CLOCKS_PER_SEC);
double Tim = max(now - sT,0.0001); // time taken for this part
double FPS = (n+1-sf)/Tim;
double SPF = 1.0/FPS;
dprintf("%s%6d] %6.2f%% nFrms=%d T=%.3fsec : %.2fFpS %.6fSpF",
myName,n,(n+1)*100.0/frames,n-sf+1,Tim,FPS,SPF);
sf=n+1; // next time start frame
sT=now; // next time start time
++part; // next time part number
stopf = frames * part / parts; // next time stop frame
}
if((n & 0x7F)==0) {
Sleep(0); // yield process for a little bit
}
}
if(debug) {
double Tim = max(double(clock()) / double(CLOCKS_PER_SEC) - start_T,0.0001);
double FPS = frames/Tim;
double SPF = 1.0/FPS;
dprintf("%sTime=%.3fsecs (%.3fmins) : Avg %.3fFpS %.6fSpF",myName,Tim,Tim/60.0,FPS,SPF);
}
} else if(bf!=NULL) {
__int64 s,e;
for(s=0; s < vi.num_audio_samples; s+= nsamples) {
e = s + nsamples;
if(e > vi.num_audio_samples)
e = vi.num_audio_samples;
child->GetAudio((void*)bf, s, e-s, env);
}
}
if(bf!=NULL) {
delete [] bf;
}
return 0;
}

#ifdef AVISYNTH_PLUGIN_25
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
#else
const AVS_Linkage *AVS_linkage = 0;
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
AVS_linkage = vectors;
#endif
env->AddFunction("ForceProcess", "c[Video]b[Audio]b[debug]b", ForceProcess, 0);
return "`ForceProcess' ForceProcess plugin";
}

amayra
25th July 2018, 09:13
thank you StainlessS
and thanks for source code i really love to read and study it

StainlessS
25th July 2018, 13:40
thank you StainlessS
and thanks for source code i really love to read and study it

Ok then just a little info, this line

PVideoFrame src = child->GetFrame(n,env); // Force decoding. MUST assign to PVideoFrame


I initially did not bother to assign to anything (I called it, it should be OK), but with some filters it worked, and with some it did not, no real concrete idea why but maybe something to do with the eg ScriptClip(after_frame=true/false) type thing.
When it did cause problems, it seemed like all filters except for the very last one (prior to ForceProcess) were prodded into doing whatever it was that they were supposed to do, but sometimes, the very last one did not wholly complete (nearly but not quite).

Anyways, must assign to variable or sometimes not guaranteed to do as required.

(everybody else is bored ******* by above, sorry).