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 >
C/C++ Source or Header  |  2014-10-16  |  39KB  |  1,437 lines

  1. // This program is free software; you can redistribute it and/or modify
  2. // it under the terms of the GNU General Public License as published by
  3. // the Free Software Foundation; either version 2 of the License, or
  4. // (at your option) any later version.
  5.  
  6. #include "stdafx.h"
  7. #include "utility.h"
  8. #include "ProcessInfo.h"
  9. #include "timer.h"
  10.  
  11. using namespace std;
  12.  
  13. #ifdef AVS64
  14.     #include "avisynth26.h"
  15.     const AVS_Linkage *AVS_linkage = 0;
  16. #else
  17.     #include "avisynth25.h"
  18. #endif
  19.  
  20. #define COLOR_AVSM_VERSION      FG_HRED | BG_BLACK
  21. #define COLOR_AVISYNTH_VERSION  FG_HGREEN | BG_BLACK
  22. #define COLOR_EMPHASIS          FG_WHITE | BG_BLACK
  23. #define COLOR_ERROR             FG_HCYAN | BG_BLACK
  24.  
  25.  
  26. struct sAvisynthInfo
  27. {
  28.     string sDLLPath;
  29.     string sErrorMsg;
  30.     int    iInterfaceVersion;
  31.     string sVersion;
  32.     string sVersionString;
  33.     BOOL   bAVSLinkage;
  34.     BOOL   bIsCompatible;
  35.     BOOL   bIsMTVersion;
  36.     BOOL   bLoadError;
  37. } AVSDLLInfo;
  38.  
  39.  
  40. struct sINISettings
  41. {
  42.     BOOL     bCreateLog;
  43.     BOOL     bPauseBeforeExit;
  44.     __int64  iStartFrame;
  45.     __int64  iStopFrame;
  46.     string   sFrameRange;
  47.     BOOL     bInvokeDistributor;
  48.     BOOL     bAllowOnlyOneInstance;
  49.     BOOL     bLogEstimatedTime;
  50.     BOOL     bUseColor;
  51. } settings;
  52.  
  53. typedef struct sPerformanceData
  54. {
  55.     unsigned int frame_low;
  56.     unsigned int frame_high;
  57.     double fps;
  58.     WORD  cpu_usage;
  59.     DWORD phys_mem;
  60.     DWORD virt_mem;
  61.     WORD num_threads;
  62. } perfdata;
  63.  
  64. CUtils utils;
  65. CTimer timer;
  66.  
  67. unsigned int CalculateFrameInterval(string &s_avsfile, string &s_avserror);
  68. string CreateLogFile(string &s_avsfile, string &s_logbuffer, perfdata * cs_pdata, unsigned int ui_index, string &s_avserror, unsigned int ui_frameinterval);
  69. string ParseINIFile();
  70. BOOL GetAvisynthInfo();
  71. BYTE CheckAvisynthDLL(BOOL &avs_linkage);
  72. BOOL GetAvisynthVersion(string &sMsg, BOOL &bIsMTVersion);
  73. void PrintUsage();
  74. void Pause();
  75. void printcon(WORD wAttributes, const char *fmt, ...);
  76.  
  77. int main(int argc, char* argv[])
  78. {
  79.     int iRet = 0;
  80.     string sAVSMVersion = "";
  81.     if (!utils.GetProductVersion(sAVSMVersion))
  82.     {
  83.         printcon(COLOR_ERROR, "\nCannot retrieve product version:\n%s\n", utils.OSErrorMessage().c_str());
  84.         Pause();
  85.         return -1;
  86.     }
  87.  
  88.     #ifdef AVS64
  89.         sAVSMVersion += " (x64)";
  90.     #else
  91.         sAVSMVersion += " (x86)";
  92.     #endif
  93.  
  94.     string sRet = ParseINIFile();
  95.     if (sRet != "")
  96.     {
  97.         printcon(COLOR_ERROR, sRet.c_str());
  98.         Pause();
  99.         return -1;
  100.     }
  101.  
  102.     printcon(COLOR_AVSM_VERSION, "\nAVSMeter %s by Groucho2004\n", sAVSMVersion.c_str());
  103.  
  104.     string sConsoleOut = "";
  105.     unsigned int uiConsoleWidth = utils.GetConsoleWidth();
  106.     string sArg = "";
  107.     string sArgTest = "";
  108.     string sAVSFile = "";
  109.     string sLogBuffer = "";
  110.     perfdata * PerformanceData = 0;
  111.     unsigned int uiPDIndex = 0;
  112.     BOOL bEarlyExit = TRUE;
  113.     BOOL bInfoOnly = FALSE;
  114.     string sAVSError = "";
  115.     unsigned int uiFrameInterval = 0;
  116.  
  117.     BOOL bRet = GetAvisynthInfo();
  118.  
  119.     if (!bRet)
  120.     {
  121.         if (AVSDLLInfo.bLoadError)
  122.         {
  123.             printcon(COLOR_ERROR, "\nCannot load avisynth.dll:\n%s\n", utils.OSErrorMessage().c_str());
  124.             Pause();
  125.             return -1;
  126.         }
  127.  
  128.         if (!AVSDLLInfo.bIsCompatible)
  129.         {
  130.             #ifdef AVS64
  131.                 printcon(COLOR_ERROR, "\nCannot load avisynth.dll.\nMake sure you are using a 64 Bit version.\n");
  132.             #else
  133.                 printcon(COLOR_ERROR, "\nCannot load avisynth.dll.\nMake sure you are using a 32 Bit version.\n");
  134.             #endif
  135.  
  136.             Pause();
  137.             return -1;
  138.         }
  139.  
  140.         if (AVSDLLInfo.sErrorMsg != "")
  141.         {
  142.             printcon(COLOR_ERROR, "\n%s\n", AVSDLLInfo.sErrorMsg.c_str());
  143.             Pause();
  144.             return -1;
  145.         }
  146.     }
  147.  
  148.  
  149.     if (!AVSDLLInfo.bAVSLinkage)
  150.     {
  151.         #ifdef AVS64
  152.             printcon(COLOR_ERROR, "\nAvisynth 2.6 x64 is required.\n");
  153.             Pause();
  154.             return -1;
  155.         #endif
  156.     }
  157.  
  158.     printcon(COLOR_AVISYNTH_VERSION, "\r%s", AVSDLLInfo.sVersionString.c_str());
  159.     if (AVSDLLInfo.bIsMTVersion)
  160.         printcon(COLOR_EMPHASIS, " (%s) (MT)\n", AVSDLLInfo.sVersion.c_str());
  161.     else
  162.         printcon(COLOR_EMPHASIS, " (%s)\n", AVSDLLInfo.sVersion.c_str());
  163.  
  164.     if (settings.bAllowOnlyOneInstance)
  165.     {
  166.         CreateMutex(NULL, TRUE, "__avsmeter__single__instance__lock__");
  167.         if (GetLastError() == ERROR_ALREADY_EXISTS)
  168.         {
  169.             printcon(COLOR_ERROR, "\nOne instance of AVSMeter is already running\n");
  170.             Pause();
  171.             return -1;
  172.         }
  173.     }
  174.  
  175.  
  176.     if (argc < 2)
  177.     {
  178.         PrintUsage();
  179.         Pause();
  180.         return -1;
  181.     }
  182.  
  183.     for (int iArg = 1; iArg < argc; iArg++)
  184.     {
  185.         sArg = argv[iArg];
  186.         sArgTest = sArg;
  187.         utils.StrToLC(sArgTest);
  188.         utils.StrTrim(sArgTest);
  189.  
  190.         if (sArgTest.length() > 4)
  191.         {
  192.             if (sArgTest.substr(sArgTest.length() - 4) == ".avs")
  193.             {
  194.                 LPTSTR lpPart;
  195.                 char szOut[2050];
  196.                 if (::GetFullPathName(argv[iArg], 2048, szOut, &lpPart))
  197.                 {
  198.                     sAVSFile = szOut;
  199.                     if (!utils.FileExists(sAVSFile))
  200.                     {
  201.                         sConsoleOut = utils.StrFormat("\nFile not found: \"%s\"\n", sArg.c_str());
  202.                         printcon(COLOR_ERROR, "%s", sConsoleOut.c_str());
  203.                         Pause();
  204.                         return -1;
  205.                     }
  206.                 }
  207.             }
  208.             continue;
  209.         }
  210.  
  211.         else if (sArgTest.length() == 2)
  212.         {
  213.             if (sArgTest == "-l")
  214.             {
  215.                 settings.bCreateLog = TRUE;
  216.                 continue;
  217.             }
  218.             else if (sArgTest == "-i")
  219.             {
  220.                 bInfoOnly = TRUE;
  221.                 continue;
  222.             }
  223.             else
  224.             {
  225.                 printcon(COLOR_ERROR, "\nInvalid argument: \"%s\"\n", sArg.c_str());
  226.                 Pause();
  227.                 return -1;
  228.             }
  229.         }
  230.  
  231.         else
  232.         {
  233.             printcon(COLOR_ERROR, "\nInvalid argument: \"%s\"\n", sArg.c_str());
  234.             Pause();
  235.             return -1;
  236.         }
  237.     }
  238.  
  239.     if (sAVSFile == "")
  240.     {
  241.         printcon(COLOR_ERROR, "\nNo script file specified\n");
  242.         Pause();
  243.         return -1;
  244.     }
  245.  
  246.     if (!bInfoOnly)
  247.     {
  248.         sAVSError = "";
  249.         printf("\r%s\r", utils.StrPad("Analysing script...", uiConsoleWidth).c_str());
  250.         uiFrameInterval = CalculateFrameInterval(sAVSFile, sAVSError);
  251.         printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  252.         if ((uiFrameInterval == 0) || (sAVSError != ""))
  253.         {
  254.             printcon(COLOR_ERROR, "\n%s\n", sAVSError.c_str());
  255.             Pause();
  256.             return -1;
  257.         }
  258.     }
  259.  
  260.  
  261.     HINSTANCE hDLL = ::LoadLibrary("avisynth");
  262.     if (!hDLL)
  263.     {
  264.         printcon(COLOR_ERROR, "\nCannot load avisynth.dll\n");
  265.         Pause();
  266.         return -1;
  267.     }
  268.  
  269.     try
  270.     {
  271.         IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
  272.         if (!CreateEnvironment)
  273.         {
  274.             printcon(COLOR_ERROR, "\nFailed to load CreateScriptEnvironment()\n");
  275.             Pause();
  276.             return -1;
  277.         }
  278.  
  279.         IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
  280.         if (!AVS_env)
  281.         {
  282.             printcon(COLOR_ERROR, "\nCould not create IScriptenvironment\n");
  283.             Pause();
  284.             return -1;
  285.         }
  286.  
  287.         #ifdef AVS64
  288.             AVS_linkage = AVS_env->GetAVSLinkage();
  289.         #endif
  290.  
  291.         AVSValue AVS_main;
  292.         AVSValue AVS_temp;
  293.         PClip AVS_clip;
  294.         VideoInfo    AVS_vidinfo;
  295.  
  296.         AVS_main = AVS_env->Invoke("Import", sAVSFile.c_str());
  297.  
  298.         if (!AVS_main.IsClip())
  299.         {
  300.             sConsoleOut = utils.StrFormat("\"%s\":\nScript did not return a video clip", sAVSFile.c_str());
  301.             AVS_env->ThrowError(sConsoleOut.c_str());
  302.         }
  303.  
  304.         BOOL bIsMTVersion = TRUE;
  305.         int iMTMode = 0;
  306.         try
  307.         {
  308.             AVS_temp = AVS_env->Invoke("GetMTMode", false);
  309.             iMTMode = AVS_temp.IsInt() ? AVS_temp.AsInt() : 0;
  310.             if ((iMTMode > 0) && (iMTMode < 5) && settings.bInvokeDistributor)
  311.                 AVS_main = AVS_env->Invoke("Distributor", AVS_main);
  312.         }
  313.         catch (IScriptEnvironment::NotFound)
  314.         {
  315.             bIsMTVersion = FALSE;
  316.         }
  317.  
  318.         AVS_clip = AVS_main.AsClip();
  319.         AVS_vidinfo = AVS_clip->GetVideoInfo();
  320.         unsigned int uiFrames = (unsigned int)AVS_vidinfo.num_frames;
  321.         __int64 iMilliSeconds = (__int64)((((double)uiFrames * (double)AVS_vidinfo.fps_denominator * 1000.0) / (double)AVS_vidinfo.fps_numerator) + 0.5);
  322.  
  323.         sLogBuffer += "[General info]\n";
  324.         sConsoleOut = utils.StrFormat("Log file created with:   AVSMeter %s", sAVSMVersion.c_str());
  325.         sLogBuffer += sConsoleOut + "\n";
  326.  
  327.         sConsoleOut = utils.StrFormat("Avisynth version:        %s", AVSDLLInfo.sVersionString.c_str());
  328.         if (AVSDLLInfo.bIsMTVersion)
  329.             sConsoleOut += utils.StrFormat(" (%s) (MT)", AVSDLLInfo.sVersion.c_str());
  330.         else
  331.             sConsoleOut += utils.StrFormat(" (%s)", AVSDLLInfo.sVersion.c_str());
  332.  
  333.         sLogBuffer += sConsoleOut + "\n";
  334.  
  335.         printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  336.  
  337.         if (bIsMTVersion)
  338.         {
  339.             sConsoleOut = utils.StrFormat("Active MT Mode: %d", iMTMode);
  340.             printf("\r%s\n", sConsoleOut.c_str());
  341.             sLogBuffer += "                         " + sConsoleOut + "\n";
  342.         }
  343.  
  344.         sLogBuffer += "\n\n[Clip info]\n";
  345.  
  346.         sConsoleOut = utils.StrFormat("Number of frames:          %11u", AVS_vidinfo.num_frames);
  347.         printf("\n%s", sConsoleOut.c_str());
  348.         sLogBuffer += sConsoleOut + "\n";
  349.  
  350.         sConsoleOut = utils.StrFormat("Length (hh:mm:ss.ms):  %s", timer.FormatTimeString(iMilliSeconds, TRUE).c_str());
  351.         printf("\n%s", sConsoleOut.c_str());
  352.         sLogBuffer += sConsoleOut + "\n";
  353.  
  354.         sConsoleOut = utils.StrFormat("Frame width:               %11u", AVS_vidinfo.width);
  355.         printf("\n%s", sConsoleOut.c_str());
  356.         sLogBuffer += sConsoleOut + "\n";
  357.  
  358.         sConsoleOut = utils.StrFormat("Frame height:              %11u", AVS_vidinfo.height);
  359.         printf("\n%s", sConsoleOut.c_str());
  360.         sLogBuffer += sConsoleOut + "\n";
  361.  
  362.         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);
  363.         printf("\n%s", sConsoleOut.c_str());
  364.         sLogBuffer += sConsoleOut + "\n";
  365.  
  366.         sConsoleOut = "Colorspace:                    ";
  367.         printf("\n%s", sConsoleOut.c_str());
  368.         sLogBuffer += sConsoleOut;
  369.  
  370.         if (AVS_vidinfo.IsYV411())
  371.             sConsoleOut = "  YV411";
  372.         else if (AVS_vidinfo.IsYV24())
  373.             sConsoleOut = "   YV24";
  374.         else if (AVS_vidinfo.IsYV16())
  375.             sConsoleOut = "   YV16";
  376.         else if (AVS_vidinfo.IsY8())
  377.             sConsoleOut = "     Y8";
  378.         else if (AVS_vidinfo.IsYV12())
  379.             sConsoleOut = "   YV12";
  380.         else if (AVS_vidinfo.IsYUY2())
  381.             sConsoleOut = "   YUY2";
  382.         else if (AVS_vidinfo.IsRGB24())
  383.             sConsoleOut = "  RGB24";
  384.         else if (AVS_vidinfo.IsRGB32())
  385.             sConsoleOut = "  RGB32";
  386.         else
  387.             sConsoleOut = "Unknown";
  388.  
  389.         printf("%s\n", sConsoleOut.c_str());
  390.         sLogBuffer += sConsoleOut + "\n";
  391.  
  392.         sConsoleOut = "Audio channels:    ";
  393.         sLogBuffer += sConsoleOut;
  394.         if (AVS_vidinfo.AudioChannels())
  395.             sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.AudioChannels());
  396.         else
  397.             sConsoleOut = "                n/a";
  398.  
  399.         sLogBuffer += sConsoleOut + "\n";
  400.  
  401.         sConsoleOut = "Audio bits/sample: ";
  402.         sLogBuffer += sConsoleOut;
  403.         if (AVS_vidinfo.SampleType())
  404.             sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.SampleType());
  405.         else
  406.             sConsoleOut = "                n/a";
  407.  
  408.         sLogBuffer += sConsoleOut + "\n";
  409.  
  410.         sConsoleOut = "Audio sample rate: ";
  411.         sLogBuffer += sConsoleOut;
  412.         if (AVS_vidinfo.SamplesPerSecond())
  413.             sConsoleOut = utils.StrFormat("%19d", AVS_vidinfo.SamplesPerSecond());
  414.         else
  415.             sConsoleOut = "                n/a";
  416.  
  417.         sLogBuffer += sConsoleOut + "\n";
  418.  
  419.         sConsoleOut = "Audio samples:     ";
  420.         sLogBuffer += sConsoleOut;
  421.         if (AVS_vidinfo.num_audio_samples)
  422.             sConsoleOut = utils.StrFormat("%19I64d", AVS_vidinfo.num_audio_samples);
  423.         else
  424.             sConsoleOut = "                n/a";
  425.  
  426.         sLogBuffer += sConsoleOut + "\n";
  427.  
  428.  
  429.         if (bInfoOnly)
  430.         {
  431.             int IVersion = AVS_clip->GetVersion();
  432.             AVS_clip = 0;
  433.             AVS_main = 0;
  434.             AVS_temp = 0;
  435.  
  436.             if (AVSDLLInfo.iInterfaceVersion >= 5)
  437.                 AVS_env->DeleteScriptEnvironment();
  438.             else
  439.                 AVS_env->~IScriptEnvironment();
  440.  
  441.             if (settings.bCreateLog)
  442.             {
  443.                 PerformanceData = new perfdata[1];
  444.                 string sLogRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
  445.                 if (sLogRet != "")
  446.                     printcon(COLOR_ERROR, sLogRet.c_str());
  447.  
  448.                 delete[] PerformanceData;
  449.             }
  450.  
  451.             #ifdef AVS64
  452.                 AVS_linkage = 0;
  453.             #endif
  454.     
  455.             ::FreeLibrary(hDLL);
  456.  
  457.             Pause();
  458.             return 0;
  459.         }
  460.  
  461.         printf("\n");
  462.  
  463.         unsigned int uiFramesToProcess = 0;
  464.         unsigned int uiFirstFrame = 0;
  465.         unsigned int uiLastFrame = uiFrames - 1;
  466.  
  467.         if (settings.iStopFrame == -1)
  468.             settings.iStopFrame = (__int64)uiFrames - 1;
  469.  
  470.         if ((settings.iStartFrame >= 0) && (settings.iStartFrame <= settings.iStopFrame) && (settings.iStopFrame < (__int64)uiFrames))
  471.         {
  472.             uiFirstFrame = (unsigned int)settings.iStartFrame;
  473.             uiLastFrame = (unsigned int)settings.iStopFrame;
  474.             uiFramesToProcess = uiLastFrame - uiFirstFrame + 1;
  475.             printf("\r%s\r", utils.StrPad("Reading frame(s)...", uiConsoleWidth).c_str());
  476.         }
  477.         else
  478.         {
  479.             printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  480.             printcon(COLOR_EMPHASIS, "\rInvalid frame range specified in INI file:\n", sConsoleOut.c_str());
  481.  
  482.             sConsoleOut = utils.StrFormat("\"%s\"", settings.sFrameRange.c_str());
  483.             printcon(COLOR_ERROR, "\r%s\n", sConsoleOut.c_str());
  484.  
  485.             sConsoleOut = utils.StrFormat("Proceed with default (%u,%u)? [y/n]", uiFirstFrame, uiLastFrame);
  486.             printcon(COLOR_EMPHASIS, "\r%s", sConsoleOut.c_str());
  487.  
  488.             int iKey = 0;
  489.             for (;;)
  490.             {
  491.                 Sleep(100);
  492.                 if (_kbhit())
  493.                 {
  494.                     printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  495.                     utils.CursorUp(1);
  496.                     printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  497.                     utils.CursorUp(1);
  498.                     printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  499.  
  500.                     iKey = _getch();
  501.                     if ((iKey == 0x59) || (iKey == 0x79))
  502.                     {
  503.                         printf("\r%s\r", utils.StrPad("Reading frame(s)...", uiConsoleWidth).c_str());
  504.                         break;
  505.                     }
  506.                     else
  507.                     {
  508.                         printf("\r%s\r", utils.StrPad("", uiConsoleWidth).c_str());
  509.                         int IVersion = AVS_clip->GetVersion();
  510.                         AVS_clip = 0;
  511.                         AVS_main = 0;
  512.                         AVS_temp = 0;
  513.             
  514.                         if (IVersion >= 5)
  515.                             AVS_env->DeleteScriptEnvironment();
  516.                         else
  517.                             AVS_env->~IScriptEnvironment();
  518.             
  519.                         if (settings.bCreateLog)
  520.                         {
  521.                             PerformanceData = new perfdata[1];
  522.                             string sLogRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
  523.                             if (sLogRet != "")
  524.                                 printf(sLogRet.c_str());
  525.             
  526.                             delete[] PerformanceData;
  527.                         }
  528.             
  529.                         #ifdef AVS64
  530.                             AVS_linkage = 0;
  531.                         #endif
  532.                 
  533.                         ::FreeLibrary(hDLL);
  534.             
  535.                         Pause();
  536.                         return 0;
  537.                     }
  538.                 }
  539.             }
  540.  
  541.             uiFirstFrame = 0;
  542.             uiLastFrame = uiFrames - 1;
  543.             uiFramesToProcess = uiFrames;
  544.         }
  545.  
  546.         while ((uiFramesToProcess / uiFrameInterval) > 1000000)
  547.         {
  548.             if (uiFrameInterval == 50000)
  549.                 uiFrameInterval = 100000;
  550.             if (uiFrameInterval == 20000)
  551.                 uiFrameInterval = 50000;
  552.             if (uiFrameInterval == 10000)
  553.                 uiFrameInterval = 20000;
  554.             if (uiFrameInterval == 5000)
  555.                 uiFrameInterval = 10000;
  556.             if (uiFrameInterval == 2000)
  557.                 uiFrameInterval = 5000;
  558.             if (uiFrameInterval == 1000)
  559.                 uiFrameInterval = 2000;
  560.             if (uiFrameInterval == 500)
  561.                 uiFrameInterval = 1000;
  562.             if (uiFrameInterval == 200)
  563.                 uiFrameInterval = 500;
  564.             if (uiFrameInterval == 100)
  565.                 uiFrameInterval = 200;
  566.             if (uiFrameInterval == 50)
  567.                 uiFrameInterval = 100;
  568.             if (uiFrameInterval == 20)
  569.                 uiFrameInterval = 50;
  570.             if (uiFrameInterval == 10)
  571.                 uiFrameInterval = 20;
  572.             if (uiFrameInterval == 1)
  573.                 uiFrameInterval = 10;
  574.         }
  575.  
  576.         unsigned int uiArraySize = (uiFramesToProcess / uiFrameInterval) + 2;
  577.  
  578.         PerformanceData = new perfdata[uiArraySize];
  579.         for (unsigned int x = 0; x < uiArraySize; x++)
  580.         {
  581.             PerformanceData[x].frame_low = 0;
  582.             PerformanceData[x].frame_high = 0;
  583.             PerformanceData[x].fps = 0.0;
  584.             PerformanceData[x].cpu_usage = 0;
  585.             PerformanceData[x].phys_mem = 0;
  586.             PerformanceData[x].virt_mem = 0;
  587.             PerformanceData[x].num_threads = 0;
  588.         }
  589.  
  590.         bEarlyExit = FALSE;
  591.         unsigned int n = 0;
  592.         BOOL bFirstScr = TRUE;
  593.         __int64 iElapsedMS = 0;
  594.         __int64 iEstimatedMS = 0;
  595.  
  596.         CProcessInfo process_info;
  597.         DWORD dwPhysicalMemPeakMB = 0;
  598.         DWORD dwVirtualMemPeakMB = 0;
  599.         DWORD dwPhysicalMemCurrentMB = 0;
  600.         DWORD dwVirtualMemCurrentMB = 0;
  601.         unsigned int uiCPUUsageAcc = 0;
  602.         unsigned int uiCPUUsageAvg = 0;
  603.         unsigned int uiCounter = 0;
  604.  
  605.         unsigned int uiCurrentFrame = 0;
  606.         double dFPSAverage = 0.0;
  607.         double dFPSCurrent = 0.0;
  608.         double dFPSMin = 1.0e+20;
  609.         double dFPSMax = 0.0;
  610.  
  611.         double dStartTime = timer.GetTimer();
  612.         double dCurrentTime = dStartTime;
  613.         double dLastDisplayTime = dStartTime;
  614.         double dLastIntervalTime = dStartTime;
  615.  
  616.         process_info.Update();
  617.  
  618.         for (uiCurrentFrame = uiFirstFrame; uiCurrentFrame <= uiLastFrame; uiCurrentFrame++)
  619.         {
  620.             PVideoFrame src_frame = AVS_clip->GetFrame(uiCurrentFrame, AVS_env);
  621.             ++n;
  622.  
  623.             if (((n % uiFrameInterval) == 0) || (n == uiFramesToProcess))
  624.             {
  625.                 dCurrentTime = timer.GetTimer();
  626.                 process_info.Update();
  627.                 ++uiCounter;
  628.  
  629.                 iElapsedMS = (__int64)(((dCurrentTime - dStartTime) * 1000.0) + 0.5);
  630.                 iEstimatedMS = (__int64)((double)uiFramesToProcess * (double)iElapsedMS / (double)n);
  631.  
  632.                 uiCPUUsageAcc += (unsigned int)process_info.wCPUUsage;
  633.                 uiCPUUsageAvg = (unsigned int)(((double)uiCPUUsageAcc / (double)uiCounter) + 0.5);
  634.  
  635.                 dwPhysicalMemCurrentMB = process_info.dwPhysicalMemMB;
  636.                 dwVirtualMemCurrentMB = process_info.dwVirtualMemMB;
  637.  
  638.                 if (dwPhysicalMemCurrentMB > dwPhysicalMemPeakMB)
  639.                     dwPhysicalMemPeakMB = dwPhysicalMemCurrentMB;
  640.                 if (dwVirtualMemCurrentMB > dwVirtualMemPeakMB)
  641.                     dwVirtualMemPeakMB = dwVirtualMemCurrentMB;
  642.  
  643.                 dFPSAverage = (double)n / (dCurrentTime - dStartTime);
  644.  
  645.                 if ((n % uiFrameInterval) == 0)
  646.                 {
  647.                     if ((dCurrentTime - dLastIntervalTime) > 0.0000001)
  648.                         dFPSCurrent = (double)uiFrameInterval / (dCurrentTime - dLastIntervalTime);
  649.                     else
  650.                         dFPSCurrent = (double)uiFrameInterval / 0.0000001;
  651.  
  652.                     if (dFPSCurrent > dFPSMax)
  653.                         dFPSMax = dFPSCurrent;
  654.                     if (dFPSCurrent < dFPSMin)
  655.                         dFPSMin = dFPSCurrent;
  656.  
  657.                     PerformanceData[uiPDIndex].frame_low = (uiCurrentFrame + 1) - uiFrameInterval;
  658.                     PerformanceData[uiPDIndex].frame_high = uiCurrentFrame;
  659.                     PerformanceData[uiPDIndex].fps = dFPSCurrent;
  660.                     PerformanceData[uiPDIndex].cpu_usage = process_info.wCPUUsage;
  661.                     PerformanceData[uiPDIndex].num_threads = process_info.wThreadCount;
  662.                     PerformanceData[uiPDIndex].phys_mem = dwPhysicalMemCurrentMB;
  663.                     PerformanceData[uiPDIndex].virt_mem = dwVirtualMemCurrentMB;
  664.                     ++uiPDIndex;
  665.  
  666.                     dLastIntervalTime = dCurrentTime;
  667.                 }
  668.  
  669.                 if ((dCurrentTime - dLastDisplayTime) >= 0.25)
  670.                 {
  671.                     uiConsoleWidth = utils.GetConsoleWidth();
  672.                     dLastDisplayTime = dCurrentTime;
  673.  
  674.                     if (!bFirstScr)
  675.                         utils.CursorUp(10);
  676.  
  677.                     bFirstScr = FALSE;
  678.                     utils.SetRGB(COLOR_EMPHASIS, settings.bUseColor);
  679.                     sConsoleOut = utils.StrFormat("Frame (current | last):         %u | %u", uiCurrentFrame, uiLastFrame);
  680.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  681.                     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());
  682.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  683.                     sConsoleOut = utils.StrFormat("CPU usage (current | average):  %u%% | %u%%", process_info.wCPUUsage, uiCPUUsageAvg);
  684.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  685.                     sConsoleOut = utils.StrFormat("Thread count:                   %u", process_info.wThreadCount);
  686.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  687.                     sConsoleOut = utils.StrFormat("Physical Memory usage:          %u MB", dwPhysicalMemCurrentMB);
  688.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  689.                     sConsoleOut = utils.StrFormat("Virtual Memory usage:           %u MB", dwVirtualMemCurrentMB);
  690.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  691.                     sConsoleOut = utils.StrFormat("Time (elapsed | estimated):     %s | %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str(), timer.FormatTimeString(iEstimatedMS, FALSE).c_str());
  692.                     printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  693.                     utils.ResetRGB(settings.bUseColor);
  694.  
  695.                     printf("\nPress \'Esc\' to cancel the process...\n\n");
  696.  
  697.                     if (_kbhit())
  698.                     {
  699.                         if (_getch() == 0x1B) //ESC
  700.                         {
  701.                             uiLastFrame = uiCurrentFrame;
  702.                             break;
  703.                         }
  704.                     }
  705.                 }
  706.             }
  707.         }
  708.  
  709.         process_info.CloseProcess();
  710.  
  711.         AVS_clip = 0;
  712.         AVS_main = 0;
  713.         AVS_temp = 0;
  714.  
  715.         if (AVSDLLInfo.iInterfaceVersion >= 5)
  716.             AVS_env->DeleteScriptEnvironment();
  717.         else
  718.             AVS_env->~IScriptEnvironment();
  719.  
  720.         sLogBuffer += "\n\n[Runtime info]\n";
  721.  
  722.         if (n >= uiFrameInterval)
  723.         {
  724.             if (!bFirstScr)
  725.                 utils.CursorUp(10);
  726.  
  727.             if (uiFirstFrame == uiLastFrame)
  728.             {
  729.                 if (uiFirstFrame == 0)
  730.                     sConsoleOut = utils.StrFormat("Frames processed:               %u", n, uiFirstFrame);
  731.                 else
  732.                     sConsoleOut = utils.StrFormat("Frames processed:               %u (%u)", n, uiFirstFrame);
  733.             }
  734.             else
  735.                 sConsoleOut = utils.StrFormat("Frames processed:               %u (%u - %u)", n, uiFirstFrame, uiLastFrame);
  736.  
  737.             utils.SetRGB(COLOR_EMPHASIS, settings.bUseColor);
  738.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  739.             sLogBuffer += sConsoleOut + "\n";
  740.  
  741.             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());
  742.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  743.             sLogBuffer += sConsoleOut + "\n";
  744.  
  745.             sConsoleOut = utils.StrFormat("CPU usage (average):            %u%%", uiCPUUsageAvg);
  746.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  747.             sLogBuffer += sConsoleOut + "\n";
  748.  
  749.             sConsoleOut = utils.StrFormat("Thread count:                   %u", process_info.wThreadCount);
  750.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  751.             sLogBuffer += sConsoleOut + "\n";
  752.  
  753.             sConsoleOut = utils.StrFormat("Physical Memory usage (peak):   %u MB", dwPhysicalMemPeakMB);
  754.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  755.             sLogBuffer += sConsoleOut + "\n";
  756.  
  757.             sConsoleOut = utils.StrFormat("Virtual Memory usage (peak):    %u MB", dwVirtualMemPeakMB);
  758.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  759.             sLogBuffer += sConsoleOut + "\n";
  760.  
  761.             if ((settings.bLogEstimatedTime) && (n < uiFramesToProcess))
  762.                 sConsoleOut = utils.StrFormat("Time (elapsed | estimated):     %s | %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str(), timer.FormatTimeString(iEstimatedMS, FALSE).c_str());
  763.             else
  764.                 sConsoleOut = utils.StrFormat("Time (elapsed):                 %s", timer.FormatTimeString(iElapsedMS, FALSE).c_str());
  765.  
  766.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  767.             sLogBuffer += sConsoleOut + "\n";
  768.  
  769.             utils.ResetRGB(settings.bUseColor);
  770.  
  771.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  772.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  773.             utils.CursorUp(2);
  774.         }
  775.         else
  776.         {
  777.             if (!bFirstScr)
  778.             {
  779.                 for (int i = 0; i <= 9; i++)
  780.                 {
  781.                     printf("\r%s", utils.StrPad("", uiConsoleWidth).c_str());
  782.                     utils.CursorUp(1);
  783.                 }
  784.             }
  785.  
  786.             sConsoleOut = "Insufficient data for measurements";
  787.             printf("\r%s\n", utils.StrPad(sConsoleOut, uiConsoleWidth).c_str());
  788.             sLogBuffer += sConsoleOut;
  789.         }
  790.     }
  791.     catch (AvisynthError err)
  792.     {
  793.         settings.bCreateLog = TRUE;
  794.         sAVSError = utils.StrFormat("%s", (PCSTR)err.msg);
  795.         iRet = -1;
  796.  
  797.         
  798.         if (bEarlyExit == FALSE)
  799.         {
  800.             utils.CursorUp(2);
  801.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  802.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  803.             utils.CursorUp(2);
  804.             printcon(COLOR_ERROR, "\r%s\n", sAVSError.c_str());
  805.         }
  806.         else
  807.             printcon(COLOR_ERROR, "\n%s\n", sAVSError.c_str());
  808.     }
  809.     catch (...)
  810.     {
  811.         settings.bCreateLog = TRUE;
  812.         iRet = -1;
  813.         if (bEarlyExit == FALSE)
  814.         {
  815.             utils.CursorUp(2);
  816.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  817.             printf("\r%s\n", utils.StrPad("", uiConsoleWidth).c_str());
  818.             utils.CursorUp(2);
  819.         }
  820.         printcon(COLOR_ERROR, "\nUnknown exception\n");
  821.     }
  822.  
  823.     #ifdef AVS64
  824.         AVS_linkage = 0;
  825.     #endif
  826.  
  827.     ::FreeLibrary(hDLL);
  828.  
  829.     if (settings.bCreateLog)
  830.     {
  831.         string sRet = CreateLogFile(sAVSFile, sLogBuffer, PerformanceData, uiPDIndex, sAVSError, uiFrameInterval);
  832.         if (sRet != "")
  833.         {
  834.             printcon(COLOR_ERROR, sRet.c_str());
  835.             Pause();
  836.             return -1;
  837.         }
  838.     }
  839.  
  840.     delete[] PerformanceData;
  841.  
  842.     Pause();
  843.  
  844.     return iRet;
  845. }
  846.  
  847.  
  848. string ParseINIFile()
  849. {
  850.     string sRet = "";
  851.     string sProgramPath = "";
  852.     string sINIFile = "";
  853.     string sTemp = "";
  854.  
  855.     char szPath[2050];
  856.     if (::GetModuleFileName(NULL, szPath, 2048) > 0)
  857.     {
  858.         sProgramPath = utils.StrFormat("%s", szPath);
  859.         size_t i = 0;
  860.         for (i = (sProgramPath.length() - 1); i > 0; i--)
  861.         {
  862.          if (sProgramPath[i] == '\\')
  863.             break;
  864.         }
  865.         sProgramPath = sProgramPath.substr(0, i);
  866.         sINIFile = sProgramPath + "\\AVSMeter.ini";
  867.     }
  868.  
  869.     settings.bCreateLog = FALSE;
  870.     settings.bPauseBeforeExit = FALSE;
  871.     settings.iStartFrame = 0;
  872.     settings.iStopFrame = -1;
  873.     settings.bInvokeDistributor = TRUE;
  874.     settings.bAllowOnlyOneInstance = TRUE;
  875.     settings.bLogEstimatedTime = FALSE;
  876.     settings.bUseColor = TRUE;
  877.  
  878.     if (!utils.FileExists(sINIFile)) //write defaults
  879.     {
  880.         ofstream hINIFile(sINIFile.c_str());
  881.         if (!hINIFile.is_open())
  882.       {
  883.             sRet = utils.StrFormat("\nCannot create \"%s\"\n", sINIFile.c_str());
  884.             return sRet;
  885.         }
  886.         hINIFile << "CreateLog=0\n";
  887.         hINIFile << "PauseBeforeExit=0\n";
  888.         hINIFile << "FrameRange=0,-1\n";
  889.         hINIFile << "InvokeDistributor=1\n";
  890.         hINIFile << "AllowOnlyOneInstance=1\n";
  891.         hINIFile << "LogEstimatedTime=0\n";
  892.         hINIFile << "UseColor=1\n";
  893.         hINIFile.flush();
  894.         hINIFile.close();
  895.  
  896.         return "";
  897.     }
  898.  
  899.     ifstream hINIFile(sINIFile.c_str());
  900.     if (!hINIFile.is_open())
  901.     {
  902.         sRet = utils.StrFormat("\nCannot open \"%s\"\n", sINIFile.c_str());
  903.         return sRet;
  904.     }
  905.  
  906.     string sOrgLine = "";
  907.     string sCurrentLine = "";
  908.     size_t spos = 0;
  909.  
  910.     while (getline(hINIFile, sCurrentLine))
  911.     {
  912.         sOrgLine = sCurrentLine;
  913.         utils.StrToLC(sCurrentLine);
  914.         utils.StrTrim(sCurrentLine);
  915.         sCurrentLine.erase(remove(sCurrentLine.begin(), sCurrentLine.end(), ' '), sCurrentLine.end());
  916.  
  917.         if (sCurrentLine.substr(0, 9) == "createlog")
  918.         {
  919.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
  920.                 settings.bCreateLog = TRUE;
  921.         }
  922.  
  923.         if (sCurrentLine.substr(0, 15) == "pausebeforeexit")
  924.         {
  925.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
  926.                 settings.bPauseBeforeExit = TRUE;
  927.         }
  928.  
  929.         if (sCurrentLine.substr(0, 17) == "invokedistributor")
  930.         {
  931.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
  932.                 settings.bInvokeDistributor = FALSE;
  933.         }
  934.  
  935.         if (sCurrentLine.substr(0, 20) == "allowonlyoneinstance")
  936.         {
  937.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
  938.                 settings.bAllowOnlyOneInstance = FALSE;
  939.         }
  940.  
  941.         if (sCurrentLine.substr(0, 16) == "logestimatedtime")
  942.         {
  943.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "1")
  944.                 settings.bLogEstimatedTime = TRUE;
  945.         }
  946.  
  947.         if (sCurrentLine.substr(0, 9) == "usecolor")
  948.         {
  949.             if (sCurrentLine.substr(sCurrentLine.length() - 1) == "0")
  950.                 settings.bUseColor = FALSE;
  951.         }
  952.  
  953.         if (sCurrentLine.substr(0, 11) == "framerange=")
  954.         {
  955.             settings.sFrameRange = sOrgLine;
  956.             settings.iStartFrame = 0xFFFFFFFFFF;
  957.             settings.iStopFrame = 0xFFFFFFFFFF;
  958.  
  959.             sTemp = sCurrentLine.substr(11);
  960.             if (sTemp.length() < 3)
  961.                 continue;
  962.  
  963.             spos = sTemp.find(",");
  964.             if ((spos < 1) || (spos > 27))
  965.                 continue;
  966.  
  967.             if ((utils.IsNumeric(sTemp.substr(0, spos))) && (utils.IsNumeric(sTemp.substr(spos + 1))))
  968.             {
  969.                 settings.iStartFrame = _atoi64(sTemp.substr(0, spos).c_str());
  970.                 settings.iStopFrame = _atoi64(sTemp.substr(spos + 1).c_str());
  971.             }
  972.         }
  973.     }
  974.  
  975.     hINIFile.close();
  976.  
  977.     return sRet;
  978. }
  979.  
  980.  
  981. string CreateLogFile(string &s_avsfile, string &s_logbuffer, perfdata * cs_pdata, unsigned int ui_index, string &s_avserror, unsigned int ui_frameinterval)
  982. {
  983.     string sRet = "";
  984.     string sAVSBuffer = "";
  985.     string sCurrentLine = "";
  986.  
  987.     ifstream hAVSFile(s_avsfile.c_str());
  988.     if (!hAVSFile.is_open())
  989.     {
  990.         sRet = utils.StrFormat("\nCannot open \"%s\"\n", s_avsfile.c_str());
  991.         return sRet;
  992.     }
  993.  
  994.     while (getline(hAVSFile, sCurrentLine))
  995.         sAVSBuffer += sCurrentLine + "\n";
  996.  
  997.     hAVSFile.close();
  998.  
  999.     string sLogFile = "";
  1000.     size_t ilen = s_avsfile.length();
  1001.  
  1002.     if (ilen > 4)
  1003.         sLogFile = s_avsfile.substr(0, ilen - 4) + ".log";
  1004.     else
  1005.         sLogFile = s_avsfile + ".log";
  1006.  
  1007.     ofstream hLogFile(sLogFile.c_str());
  1008.     if (!hLogFile.is_open())
  1009.     {
  1010.         sRet = utils.StrFormat("\nCannot create \"%s\"\n", sLogFile.c_str());
  1011.         return sRet;
  1012.     }
  1013.  
  1014.     string sLog = "";
  1015.  
  1016.     sLog = s_logbuffer + "\n";
  1017.     hLogFile << sLog;
  1018.     sLog = "\n[Script]\n" + sAVSBuffer + "\n";
  1019.     hLogFile << sLog;
  1020.  
  1021.     if (ui_index > 0)
  1022.     {
  1023.         if (ui_frameinterval == 1)
  1024.             sLog = "\n[Performance data]\n       Frame    Frames/sec   Time/frame(ms)   CPU(%)   Threads   PhysMEM(MB)   VirtMEM(MB)\n";
  1025.         else
  1026.             sLog = "\n[Performance data]\n       Frame interval    Frames/sec   Time/frame(ms)   CPU(%)   Threads   PhysMEM(MB)   VirtMEM(MB)\n";
  1027.  
  1028.         hLogFile << sLog;
  1029.  
  1030.         string stemp1 = "";
  1031.         string stemp2 = "";
  1032.         if (ui_index > 0)
  1033.         {
  1034.             for (unsigned int i = 0; i < ui_index; i++)
  1035.             {
  1036.                 if (ui_frameinterval == 1)
  1037.                 {
  1038.                     stemp1 = utils.StrFormat("%u", cs_pdata[i].frame_low);
  1039.                     string spad((12 - stemp1.length()), ' ');
  1040.                     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);
  1041.                 }
  1042.                 else
  1043.                 {
  1044.                     stemp1 = utils.StrFormat("%u-%u", cs_pdata[i].frame_low, cs_pdata[i].frame_high);
  1045.                     string spad((21 - stemp1.length()), ' ');
  1046.                     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);
  1047.                 }
  1048.  
  1049.                 hLogFile << stemp2 + "\n";
  1050.             }
  1051.         }
  1052.     }
  1053.  
  1054.     if (s_avserror != "")
  1055.     {
  1056.         hLogFile << "\n\n[AviSynth error]\n" + s_avserror + "\n";
  1057.     }
  1058.  
  1059.     hLogFile.flush();
  1060.     hLogFile.close();
  1061.  
  1062.     return sRet;
  1063. }
  1064.  
  1065.  
  1066. void Pause()
  1067. {
  1068.     if (settings.bPauseBeforeExit)
  1069.     {
  1070.         printf("\nPress any key to exit...");
  1071.         for (;;)
  1072.         {
  1073.             Sleep(100);
  1074.             if (_kbhit())
  1075.                 break;
  1076.         }
  1077.         printf("\r%s", utils.StrPad("", utils.GetConsoleWidth()).c_str());
  1078.     }
  1079.  
  1080.     return;
  1081. }
  1082.  
  1083.  
  1084. unsigned int CalculateFrameInterval(string &s_avsfile, string &s_avserror)
  1085. {
  1086.     unsigned int uiFrameInterval = 0;
  1087.     s_avserror = "";
  1088.  
  1089.     if (!timer.TestTimer())
  1090.     {
  1091.         s_avserror = "Multimedia Timers and/or High Performance Timers are not supported";
  1092.         return uiFrameInterval;
  1093.     }
  1094.  
  1095.     HINSTANCE hDLL = ::LoadLibrary("avisynth");
  1096.     if (!hDLL)
  1097.     {
  1098.         s_avserror = "Failed to load avisynth.dll";
  1099.         return uiFrameInterval;
  1100.     }
  1101.  
  1102.     try
  1103.     {
  1104.         IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
  1105.         if (!CreateEnvironment)
  1106.         {
  1107.             s_avserror = "Failed to load CreateScriptEnvironment()";
  1108.             ::FreeLibrary(hDLL);
  1109.             return uiFrameInterval;
  1110.         }
  1111.  
  1112.         IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
  1113.         if (!AVS_env)
  1114.         {
  1115.             s_avserror = "Could not create IScriptenvironment";
  1116.             ::FreeLibrary(hDLL);
  1117.             return uiFrameInterval;
  1118.         }
  1119.  
  1120.         #ifdef AVS64
  1121.             AVS_linkage = AVS_env->GetAVSLinkage();
  1122.         #endif
  1123.  
  1124.         AVSValue AVS_main;
  1125.         AVS_main = AVS_env->Invoke("Import", s_avsfile.c_str());
  1126.  
  1127.         if (!AVS_main.IsClip()) //not a clip
  1128.             AVS_env->ThrowError("Script did not return a video clip:\n(%s)", s_avsfile.c_str());
  1129.  
  1130.         AVSValue AVS_temp;
  1131.         PClip AVS_clip;
  1132.         VideoInfo    AVS_vidinfo;
  1133.  
  1134.         int iMTMode = 0;
  1135.         try
  1136.         {
  1137.             AVS_temp = AVS_env->Invoke("GetMTMode", false);
  1138.             iMTMode = AVS_temp.IsInt() ? AVS_temp.AsInt() : 0;
  1139.             if ((iMTMode > 0) && (iMTMode < 5) && settings.bInvokeDistributor)
  1140.                 AVS_main = AVS_env->Invoke("Distributor", AVS_main);
  1141.         }
  1142.         catch (IScriptEnvironment::NotFound)
  1143.         {
  1144.         }
  1145.  
  1146.         AVS_clip = AVS_main.AsClip();
  1147.         AVS_vidinfo = AVS_clip->GetVideoInfo();
  1148.         unsigned int uiTotalFrames = (unsigned int)AVS_vidinfo.num_frames;
  1149.  
  1150.         if (uiTotalFrames < 1)
  1151.             AVS_env->ThrowError("Script did not return a video clip:\n(%s)", s_avsfile.c_str());
  1152.  
  1153.         unsigned int uif = 0;
  1154.         
  1155.         double dT1 = 0.0;
  1156.         double dT2 = 0.0;
  1157.         double dTDelta = 0.0;
  1158.         BOOL bTimerWrap = TRUE;
  1159.  
  1160.         while (bTimerWrap)
  1161.         {
  1162.             bTimerWrap = FALSE;
  1163.             dT1 = timer.GetMMTimer();
  1164.             for (;;)
  1165.             {
  1166.                 PVideoFrame src_frame = AVS_clip->GetFrame(uif, AVS_env);
  1167.                 ++uif;
  1168.  
  1169.                 dT2 = timer.GetMMTimer();
  1170.                 dTDelta = (dT2 - dT1) * 1000.0; //ms
  1171.  
  1172.                 if (dTDelta < 0.0)
  1173.                 {
  1174.                     bTimerWrap = TRUE;
  1175.                     break;
  1176.                 }
  1177.  
  1178.                 if ((dTDelta >= 4000.0) || (uif == uiTotalFrames))
  1179.                     break;
  1180.             }
  1181.         }
  1182.  
  1183.         uiFrameInterval = 50000;
  1184.         double dAverageFrameTime = 0.0;
  1185.         if (dTDelta > 200)
  1186.             dAverageFrameTime = dTDelta / (double)uif;
  1187.  
  1188.         if (dAverageFrameTime > 0.001)
  1189.             uiFrameInterval = 20000;
  1190.         if (dAverageFrameTime > 0.002)
  1191.             uiFrameInterval = 10000;
  1192.         if (dAverageFrameTime > 0.004)
  1193.             uiFrameInterval = 5000;
  1194.         if (dAverageFrameTime > 0.010)
  1195.             uiFrameInterval = 2000;
  1196.         if (dAverageFrameTime > 0.020)
  1197.             uiFrameInterval = 1000;
  1198.         if (dAverageFrameTime > 0.040)
  1199.             uiFrameInterval = 500;
  1200.         if (dAverageFrameTime > 0.100)
  1201.             uiFrameInterval = 200;
  1202.         if (dAverageFrameTime > 0.200)
  1203.             uiFrameInterval = 100;
  1204.         if (dAverageFrameTime > 0.400)
  1205.             uiFrameInterval = 50;
  1206.         if (dAverageFrameTime > 1.000)
  1207.             uiFrameInterval = 20;
  1208.         if (dAverageFrameTime > 2.000)
  1209.             uiFrameInterval = 10;
  1210.         if (dAverageFrameTime > 20.00)
  1211.             uiFrameInterval = 1;
  1212.  
  1213.         AVS_clip = 0;
  1214.         AVS_main = 0;
  1215.         AVS_temp = 0;
  1216.  
  1217.         if (AVSDLLInfo.iInterfaceVersion >= 5)
  1218.             AVS_env->DeleteScriptEnvironment();
  1219.         else
  1220.             AVS_env->~IScriptEnvironment();
  1221.     }
  1222.     catch (AvisynthError err)
  1223.     {
  1224.         s_avserror = utils.StrFormat("%s", (PCSTR)err.msg);
  1225.         uiFrameInterval = 0;
  1226.     }
  1227.     catch (...)
  1228.     {
  1229.         s_avserror = "Unknown exception";
  1230.         uiFrameInterval = 0;
  1231.     }
  1232.  
  1233.     #ifdef AVS64
  1234.         AVS_linkage = 0;
  1235.     #endif
  1236.  
  1237.     ::FreeLibrary(hDLL);
  1238.  
  1239.     return uiFrameInterval;
  1240. }
  1241.  
  1242.  
  1243. BOOL GetAvisynthInfo()
  1244. {
  1245.     AVSDLLInfo.sDLLPath = "";
  1246.     AVSDLLInfo.bAVSLinkage = FALSE;
  1247.     AVSDLLInfo.bIsCompatible = TRUE;
  1248.     AVSDLLInfo.bIsMTVersion = FALSE;
  1249.     AVSDLLInfo.iInterfaceVersion = 0;
  1250.     AVSDLLInfo.bLoadError = FALSE;
  1251.     AVSDLLInfo.sErrorMsg = "";
  1252.     AVSDLLInfo.sVersion = "";
  1253.     AVSDLLInfo.sVersionString = "Unknown Avisynth Version";
  1254.  
  1255.     try
  1256.     {
  1257.         LOADED_IMAGE li;
  1258.         BOOL bLoaded = MapAndLoad("avisynth", NULL, &li,    TRUE,    TRUE);
  1259.         if (!bLoaded)
  1260.         {
  1261.             AVSDLLInfo.bLoadError = TRUE;
  1262.             return FALSE;
  1263.         }
  1264.  
  1265.         DWORD expVA = li.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  1266.         PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(li.FileHeader, li.MappedAddress, expVA, NULL);
  1267.         DWORD rvaNames = pExp->AddressOfNames;
  1268.         DWORD *prvaNames = (DWORD*)ImageRvaToVa(li.FileHeader, li.MappedAddress, rvaNames, NULL);
  1269.         string sName = "";
  1270.         int iPos = 0;
  1271.  
  1272.         for (DWORD dwName = 0; dwName < pExp->NumberOfNames; ++dwName)
  1273.         {
  1274.             DWORD rvaName = prvaNames[dwName];
  1275.             sName = (char *)ImageRvaToVa(li.FileHeader, li.MappedAddress, rvaName, NULL);
  1276.             utils.StrToLC(sName);
  1277.  
  1278.             iPos = (int)sName.find("avs_linkage");
  1279.             if (iPos >= 0)
  1280.                 AVSDLLInfo.bAVSLinkage = TRUE;
  1281.         }
  1282.  
  1283.         UnMapAndLoad(&li);
  1284.     }
  1285.     catch (...)
  1286.     {
  1287.         AVSDLLInfo.bIsCompatible = FALSE;
  1288.     }
  1289.  
  1290.     if (!AVSDLLInfo.bIsCompatible)
  1291.         return FALSE;
  1292.  
  1293.  
  1294.     HINSTANCE hDLL = ::LoadLibrary("avisynth");
  1295.     if (!hDLL)
  1296.     {
  1297.         AVSDLLInfo.bLoadError = TRUE;
  1298.         return FALSE;
  1299.     }
  1300.  
  1301.  
  1302.     char szPath[2050];
  1303.     if (::GetModuleFileName(hDLL, szPath, 2048) > 0)
  1304.     {
  1305.         AVSDLLInfo.sDLLPath = utils.StrFormat("%s", szPath);
  1306.         
  1307.         if (utils.GetResourceInfo(AVSDLLInfo.sDLLPath))
  1308.             AVSDLLInfo.sVersion = utils.resinfo.sFixedFileVersion;
  1309.     }
  1310.  
  1311.     try
  1312.     {
  1313.         IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
  1314.         if (!CreateEnvironment)
  1315.         {
  1316.             AVSDLLInfo.sErrorMsg = "Failed to load CreateScriptEnvironment()";
  1317.             ::FreeLibrary(hDLL);
  1318.             return FALSE;
  1319.         }
  1320.  
  1321.         IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
  1322.         if (!AVS_env)
  1323.         {
  1324.             AVSDLLInfo.sErrorMsg = "Could not create IScriptenvironment";
  1325.             ::FreeLibrary(hDLL);
  1326.             return FALSE;
  1327.         }
  1328.  
  1329.         #ifdef AVS64
  1330.             AVS_linkage = AVS_env->GetAVSLinkage();
  1331.         #endif
  1332.  
  1333.         AVSValue AVS_main;
  1334.         AVS_main = AVS_env->Invoke("ColorBars", AVSValue(&AVS_main, 0));
  1335.  
  1336.         AVSValue AVS_temp;
  1337.         PClip AVS_clip;
  1338.         try
  1339.         {
  1340.             AVS_temp = AVS_env->Invoke("VersionString", AVSValue(&AVS_temp, 0));
  1341.             AVSDLLInfo.sVersionString = utils.StrFormat("%s", AVS_temp.AsString());
  1342.         }
  1343.         catch (IScriptEnvironment::NotFound)
  1344.         {
  1345.         }
  1346.  
  1347.         if ((AVS_env->FunctionExists("GetMTMode")) || (AVS_env->FunctionExists("Prefetch")))
  1348.             AVSDLLInfo.bIsMTVersion = TRUE;
  1349.  
  1350.         AVS_clip = AVS_main.AsClip();
  1351.         AVSDLLInfo.iInterfaceVersion = AVS_clip->GetVersion();
  1352.         AVS_clip = 0;
  1353.         AVS_main = 0;
  1354.         AVS_temp = 0;
  1355.  
  1356.         if (AVSDLLInfo.iInterfaceVersion >= 5)
  1357.             AVS_env->DeleteScriptEnvironment();
  1358.         else
  1359.             AVS_env->~IScriptEnvironment();
  1360.     }
  1361.     catch (AvisynthError err)
  1362.     {
  1363.         AVSDLLInfo.sErrorMsg = utils.StrFormat("%s", (PCSTR)err.msg);
  1364.     }
  1365.     catch (...)
  1366.     {
  1367.         AVSDLLInfo.sErrorMsg = "Unknown exception";
  1368.     }
  1369.  
  1370.     #ifdef AVS64
  1371.         AVS_linkage = 0;
  1372.     #endif
  1373.  
  1374.     ::FreeLibrary(hDLL);
  1375.  
  1376.     return TRUE;
  1377. }
  1378.  
  1379.  
  1380. void PrintUsage()
  1381. {
  1382.     printf("\nUsage:  AVSMeter script.avs [switches]\n\n");
  1383.     printf("Switches:\n");
  1384.     printf("-i      Display clip info only\n");
  1385.     printf("-l      Create log file\n");
  1386.  
  1387.     return;
  1388. }
  1389.  
  1390.  
  1391. void printcon(WORD wAttributes, const char *fmt, ...)
  1392. {
  1393.     if (!fmt)
  1394.         return;
  1395.  
  1396.     #define MAX_LEN 2048
  1397.     va_list args;
  1398.     va_start(args, fmt);
  1399.     unsigned int len = 256;
  1400.     char *buffer = NULL;
  1401.     int result = -1;
  1402.  
  1403.     while (result == -1)
  1404.     {
  1405.         if (buffer)
  1406.             delete [] buffer;
  1407.  
  1408.         buffer = new char [len];
  1409.         memset(buffer, ' ', sizeof(buffer));
  1410.         result = _vsnprintf(buffer, len, fmt, args);
  1411.         len *= 2;
  1412.         if (len > MAX_LEN)
  1413.         {
  1414.             delete [] buffer;
  1415.             va_end(args);
  1416.             return;
  1417.         }
  1418.     }
  1419.  
  1420.     string str(buffer);
  1421.     delete [] buffer;
  1422.     va_end(args);
  1423.  
  1424.     if (wAttributes)
  1425.     {
  1426.         utils.SetRGB(wAttributes, settings.bUseColor);
  1427.         printf(str.c_str());
  1428.         utils.ResetRGB(settings.bUseColor);
  1429.     }
  1430.     else
  1431.         printf(str.c_str());
  1432.  
  1433.     return;
  1434. }
  1435.  
  1436.  
  1437.