home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 125
/
Freelog_MarsAvril2015_No125.iso
/
Multimedia
/
AVStoDVD
/
AVStoDVD_280_Install.exe
/
AVSMeter
/
source
/
AVSMeter.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2014-10-16
|
39KB
|
1,437 lines
// 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; either version 2 of the License, or
// (at your option) any later version.
#include "stdafx.h"
#include "utility.h"
#include "ProcessInfo.h"
#include "timer.h"
using namespace std;
#ifdef AVS64
#include "avisynth26.h"
const AVS_Linkage *AVS_linkage = 0;
#else
#include "avisynth25.h"
#endif
#define COLOR_AVSM_VERSION FG_HRED | BG_BLACK
#define COLOR_AVISYNTH_VERSION FG_HGREEN | BG_BLACK
#define COLOR_EMPHASIS FG_WHITE | BG_BLACK
#define COLOR_ERROR FG_HCYAN | BG_BLACK
struct sAvisynthInfo
{
string sDLLPath;
string sErrorMsg;
int iInterfaceVersion;
string sVersion;
string sVersionString;
BOOL bAVSLinkage;
BOOL bIsCompatible;
BOOL bIsMTVersion;
BOOL bLoadError;
} AVSDLLInfo;
struct sINISettings
{
BOOL bCreateLog;
BOOL bPauseBeforeExit;
__int64 iStartFrame;
__int64 iStopFrame;
string sFrameRange;
BOOL bInvokeDistributor;
BOOL bAllowOnlyOneInstance;
BOOL bLogEstimatedTime;
BOOL bUseColor;
} settings;
typedef struct sPerformanceData
{
unsigned int frame_low;
unsigned int frame_high;
double fps;
WORD cpu_usage;
DWORD phys_mem;
DWORD virt_mem;
WORD num_threads;
} perfdata;
CUtils utils;
CTimer timer;
unsigned int CalculateFrameInterval(string &s_avsfile, string &s_avserror);
string CreateLogFile(string &s_avsfile, string &s_logbuffer, perfdata * cs_pdata, unsigned int ui_index, string &s_avserror, unsigned int ui_frameinterval);
string ParseINIFile();
BOOL GetAvisynthInfo();
BYTE CheckAvisynthDLL(BOOL &avs_linkage);
BOOL GetAvisynthVersion(string &sMsg, BOOL &bIsMTVersion);
void PrintUsage();
void Pause();
void printcon(WORD wAttributes, const char *fmt, ...);
int main(int argc, char* argv[])
{
int iRet = 0;
string sAVSMVersion = "";
if (!utils.GetProductVersion(sAVSMVersion))
{
printcon(COLOR_ERROR, "\nCannot retrieve product version:\n%s\n", utils.OSErrorMessage().c_str());
Pause();
return -1;
}
#ifdef AVS64
sAVSMVersion += " (x64)";
#else
sAVSMVersion += " (x86)";
#endif
string sRet = ParseINIFile();
if (sRet != "")
{
printcon(COLOR_ERROR, sRet.c_str());
Pause();
return -1;
}
printcon(COLOR_AVSM_VERSION, "\nAVSMeter %s by Groucho2004\n", sAVSMVersion.c_str());
string sConsoleOut = "";
unsigned int uiConsoleWidth = utils.GetConsoleWidth();
string sArg = "";
string sArgTest = "";
string sAVSFile = "";
string sLogBuffer = "";
perfdata * PerformanceData = 0;
unsigned int uiPDIndex = 0;
BOOL bEarlyExit = TRUE;
BOOL bInfoOnly = FALSE;
string sAVSError = "";
unsigned int uiFrameInterval = 0;
BOOL bRet = GetAvisynthInfo();
if (!bRet)
{
if (AVSDLLInfo.bLoadError)
{
printcon(COLOR_ERROR, "\nCannot load avisynth.dll:\n%s\n", utils.OSErrorMessage().c_str());
Pause();
return -1;
}
if (!AVSDLLInfo.bIsCompatible)
{
#ifdef AVS64
printcon(COLOR_ERROR, "\nCannot load avisynth.dll.\nMake sure you are using a 64 Bit version.\n");
#else
printcon(COLOR_ERROR, "\nCannot load avisynth.dll.\nMake sure you are using a 32 Bit version.\n");
#endif
Pause();
return -1;
}
if (AVSDLLInfo.sErrorMsg != "")
{
printcon(COLOR_ERROR, "\n%s\n", AVSDLLInfo.sErrorMsg.c_str());
Pause();
return -1;
}
}
if (!AVSDLLInfo.bAVSLinkage)
{
#ifdef AVS64
printcon(COLOR_ERROR, "\nAvisynth 2.6 x64 is required.\n");
Pause();
return -1;
#endif
}
printcon(COLOR_AVISYNTH_VERSION, "\r%s", AVSDLLInfo.sVersionString.c_str());
if (AVSDLLInfo.bIsMTVersion)
printcon(COLOR_EMPHASIS, " (%s) (MT)\n", AVSDLLInfo.sVersion.c_str());
else
printcon(COLOR_EMPHASIS, " (%s)\n", AVSDLLInfo.sVersion.c_str());
if (settings.bAllowOnlyOneInstance)
{
CreateMutex(NULL, TRUE, "__avsmeter__single__instance__lock__");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
printcon(COLOR_ERROR, "\nOne instance of AVSMeter is already running\n");
Pause();
return -1;
}
}
if (argc < 2)
{
PrintUsage();
Pause();
return -1;
}
for (int iArg = 1; iArg < argc; iArg++)
{
sArg = argv[iArg];
sArgTest = sArg;
utils.StrToLC(sArgTest);
utils.StrTrim(sArgTest);
if (sArgTest.length() > 4)
{
if (sArgTest.substr(sArgTest.length() - 4) == ".avs")
{
LPTSTR lpPart;
char szOut[2050];
if (::GetFullPathName(argv[iArg], 2048, szOut, &lpPart))
{
sAVSFile = szOut;
if (!utils.FileExists(sAVSFile))
{
sConsoleOut = utils.StrFormat("\nFile not found: \"%s\"\n", sArg.c_str());
printcon(COLOR_ERROR, "%s", sConsoleOut.c_str());
Pause();
return -1;
}
}
}
continue;
}
else if (sArgTest.length() == 2)
{
if (sArgTest == "-l")
{
settings.bCreateLog = TRUE;
continue;
}
else if (sArgTest == "-i")
{
bInfoOnly = TRUE;
continue;
}
else
{
printcon(COLOR_ERROR, "\nInvalid argument: \"%s\"\n", sArg.c_str());
Pause();
return -1;
}
}
else
{
printcon(COLOR_ERROR, "\nInvalid argument: \"%s\"\n", sArg.c_str());
Pause();
return -1;
}
}
if (sAVSFile == "")
{
printcon(COLOR_ERROR, "\nNo script file specified\n");
Pause();
return -1;
}
if (!bInfoOnly)
{
sAVSError = "";
printf("\r%s\r", utils.StrPad("Analysing script...", uiConsoleWidth).c_str());
uiFrameInterval = CalculateFrameInterval(sAVSFile, sAVSError);
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
if ((uiFrameInterval == 0) || (sAVSError != ""))
{
printcon(COLOR_ERROR, "\n%s\n", sAVSError.c_str());
Pause();
return -1;
}
}
HINSTANCE hDLL = ::LoadLibrary("avisynth");
if (!hDLL)
{
printcon(COLOR_ERROR, "\nCannot load avisynth.dll\n");
Pause();
return -1;
}
try
{
IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
if (!CreateEnvironment)
{
printcon(COLOR_ERROR, "\nFailed to load CreateScriptEnvironment()\n");
Pause();
return -1;
}
IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
if (!AVS_env)
{
printcon(COLOR_ERROR, "\nCould not create IScriptenvironment\n");
Pause();
return -1;
}
#ifdef AVS64
AVS_linkage = AVS_env->GetAVSLinkage();
#endif
AVSValue AVS_main;
AVSValue AVS_temp;
PClip AVS_clip;
VideoInfo AVS_vidinfo;
AVS_main = AVS_env->Invoke("Import", sAVSFile.c_str());
if (!AVS_main.IsClip())
{
sConsoleOut = utils.StrFormat("\"%s\":\nScript did not return a video clip", sAVSFile.c_str());
AVS_env->ThrowError(sConsoleOut.c_str());
}
BOOL bIsMTVersion = TRUE;
int iMTMode = 0;
try
{
AVS_temp = AVS_env->Invoke("GetMTMode", false);
iMTMode = AVS_temp.IsInt() ? AVS_temp.AsInt() : 0;
if ((iMTMode > 0) && (iMTMode < 5) && settings.bInvokeDistributor)
AVS_main = AVS_env->Invoke("Distributor", AVS_main);
}
catch (IScriptEnvironment::NotFound)
{
bIsMTVersion = FALSE;
}
AVS_clip = AVS_main.AsClip();
AVS_vidinfo = AVS_clip->GetVideoInfo();
unsigned int uiFrames = (unsigned int)AVS_vidinfo.num_frames;
__int64 iMilliSeconds = (__int64)((((double)uiFrames * (double)AVS_vidinfo.fps_denominator * 1000.0) / (double)AVS_vidinfo.fps_numerator) + 0.5);
sLogBuffer += "[General info]\n";
sConsoleOut = utils.StrFormat("Log file created with: AVSMeter %s", sAVSMVersion.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Avisynth version: %s", AVSDLLInfo.sVersionString.c_str());
if (AVSDLLInfo.bIsMTVersion)
sConsoleOut += utils.StrFormat(" (%s) (MT)", AVSDLLInfo.sVersion.c_str());
else
sConsoleOut += utils.StrFormat(" (%s)", AVSDLLInfo.sVersion.c_str());
sLogBuffer += sConsoleOut + "\n";
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
if (bIsMTVersion)
{
sConsoleOut = utils.StrFormat("Active MT Mode: %d", iMTMode);
printf("\r%s\n", sConsoleOut.c_str());
sLogBuffer += " " + sConsoleOut + "\n";
}
sLogBuffer += "\n\n[Clip info]\n";
sConsoleOut = utils.StrFormat("Number of frames: %11u", AVS_vidinfo.num_frames);
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Length (hh:mm:ss.ms): %s", timer.FormatTimeString(iMilliSeconds, TRUE).c_str());
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Frame width: %11u", AVS_vidinfo.width);
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Frame height: %11u", AVS_vidinfo.height);
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Framerate: %11.3f (%u/%u)", (double)AVS_vidinfo.fps_numerator / (double)AVS_vidinfo.fps_denominator, AVS_vidinfo.fps_numerator, AVS_vidinfo.fps_denominator);
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = "Colorspace: ";
printf("\n%s", sConsoleOut.c_str());
sLogBuffer += sConsoleOut;
if (AVS_vidinfo.IsYV411())
sConsoleOut = " YV411";
else if (AVS_vidinfo.IsYV24())
sConsoleOut = " YV24";
else if (AVS_vidinfo.IsYV16())
sConsoleOut = " YV16";
else if (AVS_vidinfo.IsY8())
sConsoleOut = " Y8";
else if (AVS_vidinfo.IsYV12())
sConsoleOut = " YV12";
else if (AVS_vidinfo.IsYUY2())
sConsoleOut = " YUY2";
else if (AVS_vidinfo.IsRGB24())
sConsoleOut = " RGB24";
else if (AVS_vidinfo.IsRGB32())
sConsoleOut = " RGB32";
else
sConsoleOut = "Unknown";
printf("%s\n", sConsoleOut.c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = "Audio channels: ";
sLogBuffer += sConsoleOut;
if (AVS_vidinfo.AudioChannels())
sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.AudioChannels());
else
sConsoleOut = " n/a";
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = "Audio bits/sample: ";
sLogBuffer += sConsoleOut;
if (AVS_vidinfo.SampleType())
sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.SampleType());
else
sConsoleOut = " n/a";
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = "Audio sample rate: ";
sLogBuffer += sConsoleOut;
if (AVS_vidinfo.SamplesPerSecond())
sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.SamplesPerSecond());
else
sConsoleOut = " n/a";
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = "Audio samples: ";
sLogBuffer += sConsoleOut;
if (AVS_vidinfo.num_audio_samples)
sConsoleOut = utils.StrFormat("%19I64d", AVS_vidinfo.num_audio_samples);
else
sConsoleOut = " n/a";
sLogBuffer += sConsoleOut + "\n";
if (bInfoOnly)
{
int IVersion = AVS_clip->GetVersion();
AVS_clip = 0;
AVS_main = 0;
AVS_temp = 0;
if (AVSDLLInfo.iInterfaceVersion >= 5)
AVS_env->DeleteScriptEnvironment();
else
AVS_env->~IScriptEnvironment();
if (settings.bCreateLog)
{
PerformanceData = new perfdata[1];
string sLogRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
if (sLogRet != "")
printcon(COLOR_ERROR, sLogRet.c_str());
delete[] PerformanceData;
}
#ifdef AVS64
AVS_linkage = 0;
#endif
::FreeLibrary(hDLL);
Pause();
return 0;
}
printf("\n");
unsigned int uiFramesToProcess = 0;
unsigned int uiFirstFrame = 0;
unsigned int uiLastFrame = uiFrames - 1;
if (settings.iStopFrame == -1)
settings.iStopFrame = (__int64)uiFrames - 1;
if ((settings.iStartFrame >= 0) && (settings.iStartFrame <= settings.iStopFrame) && (settings.iStopFrame < (__int64)uiFrames))
{
uiFirstFrame = (unsigned int)settings.iStartFrame;
uiLastFrame = (unsigned int)settings.iStopFrame;
uiFramesToProcess = uiLastFrame - uiFirstFrame + 1;
printf("\r%s\r", utils.StrPad("Reading frame(s)...", uiConsoleWidth).c_str());
}
else
{
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
printcon(COLOR_EMPHASIS, "\rInvalid frame range specified in INI file:\n", sConsoleOut.c_str());
sConsoleOut = utils.StrFormat("\"%s\"", settings.sFrameRange.c_str());
printcon(COLOR_ERROR, "\r%s\n", sConsoleOut.c_str());
sConsoleOut = utils.StrFormat("Proceed with default (%u,%u)? [y/n]", uiFirstFrame, uiLastFrame);
printcon(COLOR_EMPHASIS, "\r%s", sConsoleOut.c_str());
int iKey = 0;
for (;;)
{
Sleep(100);
if (_kbhit())
{
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(1);
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(1);
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
iKey = _getch();
if ((iKey == 0x59) || (iKey == 0x79))
{
printf("\r%s\r", utils.StrPad("Reading frame(s)...", uiConsoleWidth).c_str());
break;
}
else
{
printf("\r%s\r", utils.StrPad("", uiConsoleWidth).c_str());
int IVersion = AVS_clip->GetVersion();
AVS_clip = 0;
AVS_main = 0;
AVS_temp = 0;
if (IVersion >= 5)
AVS_env->DeleteScriptEnvironment();
else
AVS_env->~IScriptEnvironment();
if (settings.bCreateLog)
{
PerformanceData = new perfdata[1];
string sLogRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
if (sLogRet != "")
printf(sLogRet.c_str());
delete[] PerformanceData;
}
#ifdef AVS64
AVS_linkage = 0;
#endif
::FreeLibrary(hDLL);
Pause();
return 0;
}
}
}
uiFirstFrame = 0;
uiLastFrame = uiFrames - 1;
uiFramesToProcess = uiFrames;
}
while ((uiFramesToProcess / uiFrameInterval) > 1000000)
{
if (uiFrameInterval == 50000)
uiFrameInterval = 100000;
if (uiFrameInterval == 20000)
uiFrameInterval = 50000;
if (uiFrameInterval == 10000)
uiFrameInterval = 20000;
if (uiFrameInterval == 5000)
uiFrameInterval = 10000;
if (uiFrameInterval == 2000)
uiFrameInterval = 5000;
if (uiFrameInterval == 1000)
uiFrameInterval = 2000;
if (uiFrameInterval == 500)
uiFrameInterval = 1000;
if (uiFrameInterval == 200)
uiFrameInterval = 500;
if (uiFrameInterval == 100)
uiFrameInterval = 200;
if (uiFrameInterval == 50)
uiFrameInterval = 100;
if (uiFrameInterval == 20)
uiFrameInterval = 50;
if (uiFrameInterval == 10)
uiFrameInterval = 20;
if (uiFrameInterval == 1)
uiFrameInterval = 10;
}
unsigned int uiArraySize = (uiFramesToProcess / uiFrameInterval) + 2;
PerformanceData = new perfdata[uiArraySize];
for (unsigned int x = 0; x < uiArraySize; x++)
{
PerformanceData[x].frame_low = 0;
PerformanceData[x].frame_high = 0;
PerformanceData[x].fps = 0.0;
PerformanceData[x].cpu_usage = 0;
PerformanceData[x].phys_mem = 0;
PerformanceData[x].virt_mem = 0;
PerformanceData[x].num_threads = 0;
}
bEarlyExit = FALSE;
unsigned int n = 0;
BOOL bFirstScr = TRUE;
__int64 iElapsedMS = 0;
__int64 iEstimatedMS = 0;
CProcessInfo process_info;
DWORD dwPhysicalMemPeakMB = 0;
DWORD dwVirtualMemPeakMB = 0;
DWORD dwPhysicalMemCurrentMB = 0;
DWORD dwVirtualMemCurrentMB = 0;
unsigned int uiCPUUsageAcc = 0;
unsigned int uiCPUUsageAvg = 0;
unsigned int uiCounter = 0;
unsigned int uiCurrentFrame = 0;
double dFPSAverage = 0.0;
double dFPSCurrent = 0.0;
double dFPSMin = 1.0e+20;
double dFPSMax = 0.0;
double dStartTime = timer.GetTimer();
double dCurrentTime = dStartTime;
double dLastDisplayTime = dStartTime;
double dLastIntervalTime = dStartTime;
process_info.Update();
for (uiCurrentFrame = uiFirstFrame; uiCurrentFrame <= uiLastFrame; uiCurrentFrame++)
{
PVideoFrame src_frame = AVS_clip->GetFrame(uiCurrentFrame, AVS_env);
++n;
if (((n % uiFrameInterval) == 0) || (n == uiFramesToProcess))
{
dCurrentTime = timer.GetTimer();
process_info.Update();
++uiCounter;
iElapsedMS = (__int64)(((dCurrentTime - dStartTime) * 1000.0) + 0.5);
iEstimatedMS = (__int64)((double)uiFramesToProcess * (double)iElapsedMS / (double)n);
uiCPUUsageAcc += (unsigned int)process_info.wCPUUsage;
uiCPUUsageAvg = (unsigned int)(((double)uiCPUUsageAcc / (double)uiCounter) + 0.5);
dwPhysicalMemCurrentMB = process_info.dwPhysicalMemMB;
dwVirtualMemCurrentMB = process_info.dwVirtualMemMB;
if (dwPhysicalMemCurrentMB > dwPhysicalMemPeakMB)
dwPhysicalMemPeakMB = dwPhysicalMemCurrentMB;
if (dwVirtualMemCurrentMB > dwVirtualMemPeakMB)
dwVirtualMemPeakMB = dwVirtualMemCurrentMB;
dFPSAverage = (double)n / (dCurrentTime - dStartTime);
if ((n % uiFrameInterval) == 0)
{
if ((dCurrentTime - dLastIntervalTime) > 0.0000001)
dFPSCurrent = (double)uiFrameInterval / (dCurrentTime - dLastIntervalTime);
else
dFPSCurrent = (double)uiFrameInterval / 0.0000001;
if (dFPSCurrent > dFPSMax)
dFPSMax = dFPSCurrent;
if (dFPSCurrent < dFPSMin)
dFPSMin = dFPSCurrent;
PerformanceData[uiPDIndex].frame_low = (uiCurrentFrame + 1) - uiFrameInterval;
PerformanceData[uiPDIndex].frame_high = uiCurrentFrame;
PerformanceData[uiPDIndex].fps = dFPSCurrent;
PerformanceData[uiPDIndex].cpu_usage = process_info.wCPUUsage;
PerformanceData[uiPDIndex].num_threads = process_info.wThreadCount;
PerformanceData[uiPDIndex].phys_mem = dwPhysicalMemCurrentMB;
PerformanceData[uiPDIndex].virt_mem = dwVirtualMemCurrentMB;
++uiPDIndex;
dLastIntervalTime = dCurrentTime;
}
if ((dCurrentTime - dLastDisplayTime) >= 0.25)
{
uiConsoleWidth = utils.GetConsoleWidth();
dLastDisplayTime = dCurrentTime;
if (!bFirstScr)
utils.CursorUp(10);
bFirstScr = FALSE;
utils.SetRGB(COLOR_EMPHASIS, settings.bUseColor);
sConsoleOut = utils.StrFormat("Frame (current | last): %u | %u", uiCurrentFrame, uiLastFrame);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("FPS (cur | min | max | avg): %s | %s | %s | %s", utils.StrFormatFPS(dFPSCurrent).c_str(), utils.StrFormatFPS(dFPSMin).c_str(), utils.StrFormatFPS(dFPSMax).c_str(), utils.StrFormatFPS(dFPSAverage).c_str());
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("CPU usage (current | average): %u%% | %u%%", process_info.wCPUUsage, uiCPUUsageAvg);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("Thread count: %u", process_info.wThreadCount);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("Physical Memory usage: %u MB", dwPhysicalMemCurrentMB);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("Virtual Memory usage: %u MB", dwVirtualMemCurrentMB);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sConsoleOut = utils.StrFormat("Time (elapsed | estimated): %s | %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str(), timer.FormatTimeString(iEstimatedMS, FALSE).c_str());
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
utils.ResetRGB(settings.bUseColor);
printf("\nPress \'Esc\' to cancel the process...\n\n");
if (_kbhit())
{
if (_getch() == 0x1B) //ESC
{
uiLastFrame = uiCurrentFrame;
break;
}
}
}
}
}
process_info.CloseProcess();
AVS_clip = 0;
AVS_main = 0;
AVS_temp = 0;
if (AVSDLLInfo.iInterfaceVersion >= 5)
AVS_env->DeleteScriptEnvironment();
else
AVS_env->~IScriptEnvironment();
sLogBuffer += "\n\n[Runtime info]\n";
if (n >= uiFrameInterval)
{
if (!bFirstScr)
utils.CursorUp(10);
if (uiFirstFrame == uiLastFrame)
{
if (uiFirstFrame == 0)
sConsoleOut = utils.StrFormat("Frames processed: %u", n, uiFirstFrame);
else
sConsoleOut = utils.StrFormat("Frames processed: %u (%u)", n, uiFirstFrame);
}
else
sConsoleOut = utils.StrFormat("Frames processed: %u (%u - %u)", n, uiFirstFrame, uiLastFrame);
utils.SetRGB(COLOR_EMPHASIS, settings.bUseColor);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("FPS (min | max | average): %s | %s | %s", utils.StrFormatFPS(dFPSMin).c_str(), utils.StrFormatFPS(dFPSMax).c_str(), utils.StrFormatFPS(dFPSAverage).c_str());
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("CPU usage (average): %u%%", uiCPUUsageAvg);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Thread count: %u", process_info.wThreadCount);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Physical Memory usage (peak): %u MB", dwPhysicalMemPeakMB);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
sConsoleOut = utils.StrFormat("Virtual Memory usage (peak): %u MB", dwVirtualMemPeakMB);
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
if ((settings.bLogEstimatedTime) && (n < uiFramesToProcess))
sConsoleOut = utils.StrFormat("Time (elapsed | estimated): %s | %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str(), timer.FormatTimeString(iEstimatedMS, FALSE).c_str());
else
sConsoleOut = utils.StrFormat("Time (elapsed): %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str());
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut + "\n";
utils.ResetRGB(settings.bUseColor);
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(2);
}
else
{
if (!bFirstScr)
{
for (int i = 0; i <= 9; i++)
{
printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(1);
}
}
sConsoleOut = "Insufficient data for measurements";
printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
sLogBuffer += sConsoleOut;
}
}
catch (AvisynthError err)
{
settings.bCreateLog = TRUE;
sAVSError = utils.StrFormat("%s", (PCSTR)err.msg);
iRet = -1;
if (bEarlyExit == FALSE)
{
utils.CursorUp(2);
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(2);
printcon(COLOR_ERROR, "\r%s\n", sAVSError.c_str());
}
else
printcon(COLOR_ERROR, "\n%s\n", sAVSError.c_str());
}
catch (...)
{
settings.bCreateLog = TRUE;
iRet = -1;
if (bEarlyExit == FALSE)
{
utils.CursorUp(2);
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
utils.CursorUp(2);
}
printcon(COLOR_ERROR, "\nUnknown exception\n");
}
#ifdef AVS64
AVS_linkage = 0;
#endif
::FreeLibrary(hDLL);
if (settings.bCreateLog)
{
string sRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
if (sRet != "")
{
printcon(COLOR_ERROR, sRet.c_str());
Pause();
return -1;
}
}
delete[] PerformanceData;
Pause();
return iRet;
}
string ParseINIFile()
{
string sRet = "";
string sProgramPath = "";
string sINIFile = "";
string sTemp = "";
char szPath[2050];
if (::GetModuleFileName(NULL, szPath, 2048) > 0)
{
sProgramPath = utils.StrFormat("%s", szPath);
size_t i = 0;
for (i = (sProgramPath.length() - 1); i > 0; i--)
{
if (sProgramPath[i] == '\\')
break;
}
sProgramPath = sProgramPath.substr(0, i);
sINIFile = sProgramPath + "\\AVSMeter.ini";
}
settings.bCreateLog = FALSE;
settings.bPauseBeforeExit = FALSE;
settings.iStartFrame = 0;
settings.iStopFrame = -1;
settings.bInvokeDistributor = TRUE;
settings.bAllowOnlyOneInstance = TRUE;
settings.bLogEstimatedTime = FALSE;
settings.bUseColor = TRUE;
if (!utils.FileExists(sINIFile)) //write defaults
{
ofstream hINIFile(sINIFile.c_str());
if (!hINIFile.is_open())
{
sRet = utils.StrFormat("\nCannot create \"%s\"\n", sINIFile.c_str());
return sRet;
}
hINIFile << "CreateLog=0\n";
hINIFile << "PauseBeforeExit=0\n";
hINIFile << "FrameRange=0,-1\n";
hINIFile << "InvokeDistributor=1\n";
hINIFile << "AllowOnlyOneInstance=1\n";
hINIFile << "LogEstimatedTime=0\n";
hINIFile << "UseColor=1\n";
hINIFile.flush();
hINIFile.close();
return "";
}
ifstream hINIFile(sINIFile.c_str());
if (!hINIFile.is_open())
{
sRet = utils.StrFormat("\nCannot open \"%s\"\n", sINIFile.c_str());
return sRet;
}
string sOrgLine = "";
string sCurrentLine = "";
size_t spos = 0;
while (getline(hINIFile, sCurrentLine))
{
sOrgLine = sCurrentLine;
utils.StrToLC(sCurrentLine);
utils.StrTrim(sCurrentLine);
sCurrentLine.erase(remove(sCurrentLine.begin(), sCurrentLine.end(), ' '), sCurrentLine.end());
if (sCurrentLine.substr(0, 9) == "createlog")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
settings.bCreateLog = TRUE;
}
if (sCurrentLine.substr(0, 15) == "pausebeforeexit")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
settings.bPauseBeforeExit = TRUE;
}
if (sCurrentLine.substr(0, 17) == "invokedistributor")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
settings.bInvokeDistributor = FALSE;
}
if (sCurrentLine.substr(0, 20) == "allowonlyoneinstance")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
settings.bAllowOnlyOneInstance = FALSE;
}
if (sCurrentLine.substr(0, 16) == "logestimatedtime")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
settings.bLogEstimatedTime = TRUE;
}
if (sCurrentLine.substr(0, 9) == "usecolor")
{
if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
settings.bUseColor = FALSE;
}
if (sCurrentLine.substr(0, 11) == "framerange=")
{
settings.sFrameRange = sOrgLine;
settings.iStartFrame = 0xFFFFFFFFFF;
settings.iStopFrame = 0xFFFFFFFFFF;
sTemp = sCurrentLine.substr(11);
if (sTemp.length() < 3)
continue;
spos = sTemp.find(",");
if ((spos < 1) || (spos > 27))
continue;
if ((utils.IsNumeric(sTemp.substr(0, spos))) && (utils.IsNumeric(sTemp.substr(spos + 1))))
{
settings.iStartFrame = _atoi64(sTemp.substr(0, spos).c_str());
settings.iStopFrame = _atoi64(sTemp.substr(spos + 1).c_str());
}
}
}
hINIFile.close();
return sRet;
}
string CreateLogFile(string &s_avsfile, string &s_logbuffer, perfdata * cs_pdata, unsigned int ui_index, string &s_avserror, unsigned int ui_frameinterval)
{
string sRet = "";
string sAVSBuffer = "";
string sCurrentLine = "";
ifstream hAVSFile(s_avsfile.c_str());
if (!hAVSFile.is_open())
{
sRet = utils.StrFormat("\nCannot open \"%s\"\n", s_avsfile.c_str());
return sRet;
}
while (getline(hAVSFile, sCurrentLine))
sAVSBuffer += sCurrentLine + "\n";
hAVSFile.close();
string sLogFile = "";
size_t ilen = s_avsfile.length();
if (ilen > 4)
sLogFile = s_avsfile.substr(0, ilen - 4) + ".log";
else
sLogFile = s_avsfile + ".log";
ofstream hLogFile(sLogFile.c_str());
if (!hLogFile.is_open())
{
sRet = utils.StrFormat("\nCannot create \"%s\"\n", sLogFile.c_str());
return sRet;
}
string sLog = "";
sLog = s_logbuffer + "\n";
hLogFile << sLog;
sLog = "\n[Script]\n" + sAVSBuffer + "\n";
hLogFile << sLog;
if (ui_index > 0)
{
if (ui_frameinterval == 1)
sLog = "\n[Performance data]\n Frame Frames/sec Time/frame(ms) CPU(%) Threads PhysMEM(MB) VirtMEM(MB)\n";
else
sLog = "\n[Performance data]\n Frame interval Frames/sec Time/frame(ms) CPU(%) Threads PhysMEM(MB) VirtMEM(MB)\n";
hLogFile << sLog;
string stemp1 = "";
string stemp2 = "";
if (ui_index > 0)
{
for (unsigned int i = 0; i < ui_index; i++)
{
if (ui_frameinterval == 1)
{
stemp1 = utils.StrFormat("%u", cs_pdata[i].frame_low);
string spad((12 - stemp1.length()), ' ');
stemp2 = utils.StrFormat("%s%u %13.3f %16.4f %8u %9u %13u %13u", spad.c_str(), cs_pdata[i].frame_low, cs_pdata[i].fps, 1000.0 / cs_pdata[i].fps, cs_pdata[i].cpu_usage, cs_pdata[i].num_threads, cs_pdata[i].phys_mem, cs_pdata[i].virt_mem);
}
else
{
stemp1 = utils.StrFormat("%u-%u", cs_pdata[i].frame_low, cs_pdata[i].frame_high);
string spad((21 - stemp1.length()), ' ');
stemp2 = utils.StrFormat("%s%u-%u %13.3f %16.4f %8u %9u %13u %13u", spad.c_str(), cs_pdata[i].frame_low, cs_pdata[i].frame_high, cs_pdata[i].fps, 1000.0 / cs_pdata[i].fps, cs_pdata[i].cpu_usage, cs_pdata[i].num_threads, cs_pdata[i].phys_mem, cs_pdata[i].virt_mem);
}
hLogFile << stemp2 + "\n";
}
}
}
if (s_avserror != "")
{
hLogFile << "\n\n[AviSynth error]\n" + s_avserror + "\n";
}
hLogFile.flush();
hLogFile.close();
return sRet;
}
void Pause()
{
if (settings.bPauseBeforeExit)
{
printf("\nPress any key to exit...");
for (;;)
{
Sleep(100);
if (_kbhit())
break;
}
printf("\r%s", utils.StrPad("", utils.GetConsoleWidth()).c_str());
}
return;
}
unsigned int CalculateFrameInterval(string &s_avsfile, string &s_avserror)
{
unsigned int uiFrameInterval = 0;
s_avserror = "";
if (!timer.TestTimer())
{
s_avserror = "Multimedia Timers and/or High Performance Timers are not supported";
return uiFrameInterval;
}
HINSTANCE hDLL = ::LoadLibrary("avisynth");
if (!hDLL)
{
s_avserror = "Failed to load avisynth.dll";
return uiFrameInterval;
}
try
{
IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
if (!CreateEnvironment)
{
s_avserror = "Failed to load CreateScriptEnvironment()";
::FreeLibrary(hDLL);
return uiFrameInterval;
}
IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
if (!AVS_env)
{
s_avserror = "Could not create IScriptenvironment";
::FreeLibrary(hDLL);
return uiFrameInterval;
}
#ifdef AVS64
AVS_linkage = AVS_env->GetAVSLinkage();
#endif
AVSValue AVS_main;
AVS_main = AVS_env->Invoke("Import", s_avsfile.c_str());
if (!AVS_main.IsClip()) //not a clip
AVS_env->ThrowError("Script did not return a video clip:\n(%s)", s_avsfile.c_str());
AVSValue AVS_temp;
PClip AVS_clip;
VideoInfo AVS_vidinfo;
int iMTMode = 0;
try
{
AVS_temp = AVS_env->Invoke("GetMTMode", false);
iMTMode = AVS_temp.IsInt() ? AVS_temp.AsInt() : 0;
if ((iMTMode > 0) && (iMTMode < 5) && settings.bInvokeDistributor)
AVS_main = AVS_env->Invoke("Distributor", AVS_main);
}
catch (IScriptEnvironment::NotFound)
{
}
AVS_clip = AVS_main.AsClip();
AVS_vidinfo = AVS_clip->GetVideoInfo();
unsigned int uiTotalFrames = (unsigned int)AVS_vidinfo.num_frames;
if (uiTotalFrames < 1)
AVS_env->ThrowError("Script did not return a video clip:\n(%s)", s_avsfile.c_str());
unsigned int uif = 0;
double dT1 = 0.0;
double dT2 = 0.0;
double dTDelta = 0.0;
BOOL bTimerWrap = TRUE;
while (bTimerWrap)
{
bTimerWrap = FALSE;
dT1 = timer.GetMMTimer();
for (;;)
{
PVideoFrame src_frame = AVS_clip->GetFrame(uif, AVS_env);
++uif;
dT2 = timer.GetMMTimer();
dTDelta = (dT2 - dT1) * 1000.0; //ms
if (dTDelta < 0.0)
{
bTimerWrap = TRUE;
break;
}
if ((dTDelta >= 4000.0) || (uif == uiTotalFrames))
break;
}
}
uiFrameInterval = 50000;
double dAverageFrameTime = 0.0;
if (dTDelta > 200)
dAverageFrameTime = dTDelta / (double)uif;
if (dAverageFrameTime > 0.001)
uiFrameInterval = 20000;
if (dAverageFrameTime > 0.002)
uiFrameInterval = 10000;
if (dAverageFrameTime > 0.004)
uiFrameInterval = 5000;
if (dAverageFrameTime > 0.010)
uiFrameInterval = 2000;
if (dAverageFrameTime > 0.020)
uiFrameInterval = 1000;
if (dAverageFrameTime > 0.040)
uiFrameInterval = 500;
if (dAverageFrameTime > 0.100)
uiFrameInterval = 200;
if (dAverageFrameTime > 0.200)
uiFrameInterval = 100;
if (dAverageFrameTime > 0.400)
uiFrameInterval = 50;
if (dAverageFrameTime > 1.000)
uiFrameInterval = 20;
if (dAverageFrameTime > 2.000)
uiFrameInterval = 10;
if (dAverageFrameTime > 20.00)
uiFrameInterval = 1;
AVS_clip = 0;
AVS_main = 0;
AVS_temp = 0;
if (AVSDLLInfo.iInterfaceVersion >= 5)
AVS_env->DeleteScriptEnvironment();
else
AVS_env->~IScriptEnvironment();
}
catch (AvisynthError err)
{
s_avserror = utils.StrFormat("%s", (PCSTR)err.msg);
uiFrameInterval = 0;
}
catch (...)
{
s_avserror = "Unknown exception";
uiFrameInterval = 0;
}
#ifdef AVS64
AVS_linkage = 0;
#endif
::FreeLibrary(hDLL);
return uiFrameInterval;
}
BOOL GetAvisynthInfo()
{
AVSDLLInfo.sDLLPath = "";
AVSDLLInfo.bAVSLinkage = FALSE;
AVSDLLInfo.bIsCompatible = TRUE;
AVSDLLInfo.bIsMTVersion = FALSE;
AVSDLLInfo.iInterfaceVersion = 0;
AVSDLLInfo.bLoadError = FALSE;
AVSDLLInfo.sErrorMsg = "";
AVSDLLInfo.sVersion = "";
AVSDLLInfo.sVersionString = "Unknown Avisynth Version";
try
{
LOADED_IMAGE li;
BOOL bLoaded = MapAndLoad("avisynth", NULL, &li, TRUE, TRUE);
if (!bLoaded)
{
AVSDLLInfo.bLoadError = TRUE;
return FALSE;
}
DWORD expVA = li.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(li.FileHeader, li.MappedAddress, expVA, NULL);
DWORD rvaNames = pExp->AddressOfNames;
DWORD *prvaNames = (DWORD*)ImageRvaToVa(li.FileHeader, li.MappedAddress, rvaNames, NULL);
string sName = "";
int iPos = 0;
for (DWORD dwName = 0; dwName < pExp->NumberOfNames; ++dwName)
{
DWORD rvaName = prvaNames[dwName];
sName = (char *)ImageRvaToVa(li.FileHeader, li.MappedAddress, rvaName, NULL);
utils.StrToLC(sName);
iPos = (int)sName.find("avs_linkage");
if (iPos >= 0)
AVSDLLInfo.bAVSLinkage = TRUE;
}
UnMapAndLoad(&li);
}
catch (...)
{
AVSDLLInfo.bIsCompatible = FALSE;
}
if (!AVSDLLInfo.bIsCompatible)
return FALSE;
HINSTANCE hDLL = ::LoadLibrary("avisynth");
if (!hDLL)
{
AVSDLLInfo.bLoadError = TRUE;
return FALSE;
}
char szPath[2050];
if (::GetModuleFileName(hDLL, szPath, 2048) > 0)
{
AVSDLLInfo.sDLLPath = utils.StrFormat("%s", szPath);
if (utils.GetResourceInfo(AVSDLLInfo.sDLLPath))
AVSDLLInfo.sVersion = utils.resinfo.sFixedFileVersion;
}
try
{
IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
if (!CreateEnvironment)
{
AVSDLLInfo.sErrorMsg = "Failed to load CreateScriptEnvironment()";
::FreeLibrary(hDLL);
return FALSE;
}
IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
if (!AVS_env)
{
AVSDLLInfo.sErrorMsg = "Could not create IScriptenvironment";
::FreeLibrary(hDLL);
return FALSE;
}
#ifdef AVS64
AVS_linkage = AVS_env->GetAVSLinkage();
#endif
AVSValue AVS_main;
AVS_main = AVS_env->Invoke("ColorBars", AVSValue(&AVS_main, 0));
AVSValue AVS_temp;
PClip AVS_clip;
try
{
AVS_temp = AVS_env->Invoke("VersionString", AVSValue(&AVS_temp, 0));
AVSDLLInfo.sVersionString = utils.StrFormat("%s", AVS_temp.AsString());
}
catch (IScriptEnvironment::NotFound)
{
}
if ((AVS_env->FunctionExists("GetMTMode")) || (AVS_env->FunctionExists("Prefetch")))
AVSDLLInfo.bIsMTVersion = TRUE;
AVS_clip = AVS_main.AsClip();
AVSDLLInfo.iInterfaceVersion = AVS_clip->GetVersion();
AVS_clip = 0;
AVS_main = 0;
AVS_temp = 0;
if (AVSDLLInfo.iInterfaceVersion >= 5)
AVS_env->DeleteScriptEnvironment();
else
AVS_env->~IScriptEnvironment();
}
catch (AvisynthError err)
{
AVSDLLInfo.sErrorMsg = utils.StrFormat("%s", (PCSTR)err.msg);
}
catch (...)
{
AVSDLLInfo.sErrorMsg = "Unknown exception";
}
#ifdef AVS64
AVS_linkage = 0;
#endif
::FreeLibrary(hDLL);
return TRUE;
}
void PrintUsage()
{
printf("\nUsage: AVSMeter script.avs [switches]\n\n");
printf("Switches:\n");
printf("-i Display clip info only\n");
printf("-l Create log file\n");
return;
}
void printcon(WORD wAttributes, const char *fmt, ...)
{
if (!fmt)
return;
#define MAX_LEN 2048
va_list args;
va_start(args, fmt);
unsigned int len = 256;
char *buffer = NULL;
int result = -1;
while (result == -1)
{
if (buffer)
delete [] buffer;
buffer = new char [len];
memset(buffer, ' ', sizeof(buffer));
result = _vsnprintf(buffer, len, fmt, args);
len *= 2;
if (len > MAX_LEN)
{
delete [] buffer;
va_end(args);
return;
}
}
string str(buffer);
delete [] buffer;
va_end(args);
if (wAttributes)
{
utils.SetRGB(wAttributes, settings.bUseColor);
printf(str.c_str());
utils.ResetRGB(settings.bUseColor);
}
else
printf(str.c_str());
return;
}