Added Avisynth call tracing code (disabled by default, define DEBUG_AVISYNTH_CODE to use)

Minor change in implementation of audio spectrum power scaling

Originally committed to SVN as r559.
This commit is contained in:
Niels Martin Hansen 2006-12-17 04:58:10 +00:00
parent 7bcfae18b7
commit db1e70157c
4 changed files with 121 additions and 14 deletions

View File

@ -578,13 +578,13 @@ protected:
#elif 1
// "Compressed" scale
double onethirdmaxpower = maxpower / 3, twothirdmaxpower = maxpower * 2/3;
double overscale = maxpower*8*scale - twothirdmaxpower;
double logoverscale = log(maxpower*8*scale - twothirdmaxpower);
for (int j = 0; j < window; j++) {
// First do a simple linear scale power calculation -- 8 gives a reasonable default scaling
power[j] = sqrt(out_r[j]*out_r[j] + out_i[j]*out_i[j]) * 8 * scale;
if (power[j] > maxpower * 2/3) {
double p = power[j] - twothirdmaxpower;
p = log(p) * onethirdmaxpower / log(overscale);
p = log(p) * onethirdmaxpower / logoverscale;
power[j] = p + twothirdmaxpower;
}
}

View File

@ -41,6 +41,24 @@
#ifdef __WINDOWS__
#include "options.h"
#ifdef DEBUG_AVISYNTH_CODE
#include "main.h"
#include "wx/textfile.h"
wxTextFile avs_trace_file;
void DoAvsTrace(const wxString &s)
{
if (!avs_trace_file.IsOpened()) {
if (!avs_trace_file.Open(AegisubApp::folderName + _T("avstrace.txt"))) {
avs_trace_file.Create(AegisubApp::folderName + _T("avstrace.txt"));
}
avs_trace_file.AddLine(_T(""));
avs_trace_file.AddLine(_T("======= NEW SESSION ======="));
}
avs_trace_file.AddLine(s);
avs_trace_file.Write();
}
#endif
///////////////////////////////
// Static field initialization
@ -54,15 +72,22 @@ wxMutex AviSynthWrapper::AviSynthMutex;
// AviSynth constructor
AviSynthWrapper::AviSynthWrapper() {
if (!avs_refcount) {
AVSTRACE(_T("Avisynth not loaded, trying to load it now..."));
hLib=LoadLibrary(_T("avisynth.dll"));
if (hLib == NULL)
if (hLib == NULL) {
AVSTRACE(_T("Avisynth loading failed"));
throw wxString(_T("Could not load avisynth.dll"));
}
AVSTRACE(_T("Avisynth loading successful"));
FUNC *CreateScriptEnv = (FUNC*)GetProcAddress(hLib, "CreateScriptEnvironment");
if (CreateScriptEnv == NULL)
if (CreateScriptEnv == NULL) {
AVSTRACE(_T("Failed to get address of CreateScriptEnv"));
throw wxString(_T("Failed to get function from avisynth.dll"));
}
AVSTRACE(_T("Got address of CreateScriptEnv"));
// Require Avisynth 2.5.6+?
if (Options.AsBool(_T("Allow Ancient Avisynth")))
@ -70,24 +95,34 @@ AviSynthWrapper::AviSynthWrapper() {
else
env = CreateScriptEnv(AVISYNTH_INTERFACE_VERSION);
if (env == NULL)
if (env == NULL) {
AVSTRACE(_T("Failed to create script environment"));
throw wxString(_T("Failed to create a new avisynth script environment. Avisynth is too old?"));
}
AVSTRACE(_T("Created script environment"));
// Set memory limit
int memoryMax = Options.AsInt(_T("Avisynth MemoryMax"));
if (memoryMax != 0)
if (memoryMax != 0) {
env->SetMemoryMax(memoryMax);
AVSTRACE(_T("Set Avisynth memory limit"));
}
}
avs_refcount++;
AVSTRACE(_T("Increased reference count"));
}
///////////////////////
// AviSynth destructor
AviSynthWrapper::~AviSynthWrapper() {
AVSTRACE(_T("Decreasing reference count"));
if (!--avs_refcount) {
AVSTRACE(_T("Reference count reached zero, deleting environment"));
delete env;
AVSTRACE(_T("Environment deleted"));
FreeLibrary(hLib);
AVSTRACE(_T("Free'd library, unloading complete"));
}
}

View File

@ -52,6 +52,16 @@
typedef IScriptEnvironment* __stdcall FUNC(int);
////////////////////////////
// Avisynth debugging stuff
#ifdef DEBUG_AVISYNTH_CODE
void DoAvsTrace(const wxString &s);
#define AVSTRACE(s) DoAvsTrace(s)
#else
#define AVSTRACE(s)
#endif
///////////////////////////
// AviSynth wrapping class
class AviSynthWrapper {

View File

@ -44,6 +44,7 @@
AvisynthVideoProvider::AvisynthVideoProvider(wxString _filename, wxString _subfilename) {
AVSTRACE(wxString::Format(_T("AvisynthVideoProvider: Creating new AvisynthVideoProvider: \"%s\", \"%s\""), _filename, _subfilename));
bool mpeg2dec3_priority = true;
RGB32Video = NULL;
SubtitledVideo = NULL;
@ -57,37 +58,51 @@ AvisynthVideoProvider::AvisynthVideoProvider(wxString _filename, wxString _subfi
subfilename = _subfilename;
zoom = 1.0;
AVSTRACE(_T("AvisynthVideoProvider: Loading VSFilter"));
LoadVSFilter();
AVSTRACE(_T("AvisynthVideoProvider: VSFilter loaded"));
AVSTRACE(_T("AvisynthVideoProvider: Opening video"));
RGB32Video = OpenVideo(_filename,mpeg2dec3_priority);
AVSTRACE(_T("AvisynthVideoProvider: Video opened"));
dar = GetSourceWidth()/(double)GetSourceHeight();
AVSTRACE(_T("AvisynthVideoProvider: Calculated aspect ratio"));
if( _subfilename.IsEmpty() ) SubtitledVideo = RGB32Video;
else SubtitledVideo = ApplySubtitles(subfilename, RGB32Video);
AVSTRACE(_T("AvisynthVideoProvider: Applied subtitles"));
ResizedVideo = ApplyDARZoom(zoom, dar, SubtitledVideo);
AVSTRACE(_T("AvisynthVideoProvider: Applied zoom"));
vi = ResizedVideo->GetVideoInfo();
AVSTRACE(_T("AvisynthVideoProvider: Got video info"));
AVSTRACE(_T("AvisynthVideoProvider: Done creating AvisynthVideoProvider"));
}
AvisynthVideoProvider::~AvisynthVideoProvider() {
AVSTRACE(_T("AvisynthVideoProvider: Destroying AvisynthVideoProvider"));
RGB32Video = NULL;
SubtitledVideo = NULL;
ResizedVideo = NULL;
if( data ) delete data;
AVSTRACE(_T("AvisynthVideoProvider: AvisynthVideoProvider destroyed"));
}
void AvisynthVideoProvider::RefreshSubtitles() {
AVSTRACE(_T("AvisynthVideoProvider::RefreshSubtitles: Refreshing subtitles"));
ResizedVideo = NULL;
SubtitledVideo = NULL;
SubtitledVideo = ApplySubtitles(subfilename, RGB32Video);
ResizedVideo = ApplyDARZoom(zoom,dar,SubtitledVideo);
GetFrame(last_fnum,true);
AVSTRACE(_T("AvisynthVideoProvider::RefreshSubtitles: Subtitles refreshed"));
}
void AvisynthVideoProvider::SetDAR(double _dar) {
AVSTRACE(_T("AvisynthVideoProvider::SetDAR: Setting DAR"));
dar = _dar;
ResizedVideo = NULL;
@ -96,9 +111,11 @@ void AvisynthVideoProvider::SetDAR(double _dar) {
ResizedVideo = ApplyDARZoom(zoom,dar,SubtitledVideo);
GetFrame(last_fnum,true);
AVSTRACE(_T("AvisynthVideoProvider::SetDAR: DAR set"));
}
void AvisynthVideoProvider::SetZoom(double _zoom) {
AVSTRACE(_T("AvisynthVideoProvider::SetZoom: Setting zoom"));
zoom = _zoom;
ResizedVideo = NULL;
@ -107,10 +124,13 @@ void AvisynthVideoProvider::SetZoom(double _zoom) {
ResizedVideo = ApplyDARZoom(zoom,dar,SubtitledVideo);
GetFrame(last_fnum,true);
AVSTRACE(_T("AvisynthVideoProvider::SetZoom: Zoom set"));
}
PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priority) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening video"));
wxMutexLocker lock(AviSynthMutex);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Got AVS mutex"));
AVSValue script;
bool usedDirectshow = false;
@ -124,51 +144,73 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
// Load depending on extension
if (extension == _T(".avs")) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening .avs file with Import"));
script = env->Invoke("Import", videoFilename);
} else if (extension == _T(".avi")) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Finished"));
}
else if (extension == _T(".avi")) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening .avi file with AviSource"));
try {
const char *argnames[2] = { 0, "audio" };
AVSValue args[2] = { videoFilename, false };
script = env->Invoke("AviSource", AVSValue(args,2), argnames);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Successfully opened .avi file without audio"));
} catch (AvisynthError &) {
AVSTRACE(_T("Failed to open .avi file with AviSource, switching to DirectShowSource"));
goto directshowOpen;
}
}
else if (extension == _T(".d2v") && env->FunctionExists("mpeg2dec3_Mpeg2Source") && mpeg2dec3_priority) //prefer mpeg2dec3
else if (extension == _T(".d2v") && env->FunctionExists("mpeg2dec3_Mpeg2Source") && mpeg2dec3_priority) { //prefer mpeg2dec3
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening .d2v file with mpeg2dec3_Mpeg2Source"));
script = env->Invoke("mpeg2dec3_Mpeg2Source", videoFilename);
else if (extension == _T(".d2v") && env->FunctionExists("Mpeg2Source")) //try other mpeg2source
}
else if (extension == _T(".d2v") && env->FunctionExists("Mpeg2Source")) { //try other mpeg2source
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening .d2v file with other Mpeg2Source"));
script = env->Invoke("Mpeg2Source", videoFilename);
}
else {
directshowOpen:
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Opening file with DirectShowSource"));
if (env->FunctionExists("DirectShowSource")) {
const char *argnames[3] = { 0, "video", "audio" };
AVSValue args[3] = { videoFilename, true, false };
script = env->Invoke("DirectShowSource", AVSValue(args,3), argnames);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Successfully opened file with DSS without audio"));
usedDirectshow = true;
} else
}
else {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: DSS function not found"));
throw AvisynthError("No function suitable for opening the video found");
}
}
} catch (AvisynthError &err) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Avisynth error: ") + wxString(err.msg,wxConvLocal));
throw _T("AviSynth error: ") + wxString(err.msg,wxConvLocal);
}
if (!script.AsClip()->GetVideoInfo().HasVideo())
if (!script.AsClip()->GetVideoInfo().HasVideo()) {
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: No suitable video found"));
throw _T("No usable video found in ") + _filename;
}
// Convert to RGB32
script = env->Invoke("ConvertToRGB32", script);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Converted to RGB32"));
// Directshow
if (usedDirectshow) wxMessageBox(_T("Warning! The file is being opened using Avisynth's DirectShowSource, which has unreliable seeking. Frame numbers might not match the real number. PROCEED AT YOUR OWN RISK!"),_T("DirectShowSource warning"),wxICON_EXCLAMATION);
// Cache
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Finished opening video, AVS mutex will be released now"));
return (env->Invoke("Cache", script)).AsClip();
}
PClip AvisynthVideoProvider::ApplySubtitles(wxString _filename, PClip videosource) {
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Applying subtitles"));
wxMutexLocker lock(AviSynthMutex);
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Got AVS mutex"));
// Insert subs
AVSValue script;
@ -177,17 +219,23 @@ PClip AvisynthVideoProvider::ApplySubtitles(wxString _filename, PClip videosourc
AVSValue args[2] = { videosource, temp };
try {
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Now invoking TextSub"));
script = env->Invoke("TextSub", AVSValue(args,2));
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: TextSub invoked successfully"));
} catch (AvisynthError &err) {
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Avisynth error: ") + wxString(err.msg,wxConvLocal));
throw _T("AviSynth error: ") + wxString(err.msg,wxConvLocal);
}
// Cache
AVSTRACE(_T("AvisynthVideoProvider::ApplySutitles: Subtitles applied, AVS mutex will be released now"));
return (env->Invoke("Cache", script)).AsClip();
}
PClip AvisynthVideoProvider::ApplyDARZoom(double _zoom, double _dar, PClip videosource) {
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: Applying DAR zoom"));
wxMutexLocker lock(AviSynthMutex);
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: Got AVS mutex"));
AVSValue script;
VideoInfo vil = videosource->GetVideoInfo();
@ -201,17 +249,22 @@ PClip AvisynthVideoProvider::ApplyDARZoom(double _zoom, double _dar, PClip video
throw AvisynthError("Selected resizer doesn't exist");
AVSValue args[3] = { videosource, w, h };
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: Invoking resizing function"));
script = env->Invoke(Options.AsText(_T("Video resizer")).mb_str(wxConvLocal), AVSValue(args,3));
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: Resizer invoked successfully"));
} catch (AvisynthError &err) {
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: Avisynth error: ") + wxString(err.msg,wxConvLocal));
throw _T("AviSynth error: ") + wxString(err.msg,wxConvLocal);
}
vi = script.AsClip()->GetVideoInfo();
AVSTRACE(_T("AvisynthVideoProvider::ApplyDARZoom: DAR zoom applied successfully, AVS mutex will be released now"));
return (env->Invoke("Cache",script)).AsClip();
}
wxBitmap AvisynthVideoProvider::GetFrame(int n, bool force) {
AVSTRACE(_T("AvisynthVideoProvider::GetFrame"));
if (n != last_fnum || force) {
wxMutexLocker lock(AviSynthMutex);
@ -279,6 +332,7 @@ wxBitmap AvisynthVideoProvider::GetFrame(int n, bool force) {
}
void AvisynthVideoProvider::GetFloatFrame(float* Buffer, int n) {
AVSTRACE(_T("AvisynthVideoProvider::GetFloatFrame"));
wxMutexLocker lock(AviSynthMutex);
PVideoFrame frame = ResizedVideo->GetFrame(n,env);
@ -298,13 +352,17 @@ void AvisynthVideoProvider::GetFloatFrame(float* Buffer, int n) {
}
void AvisynthVideoProvider::LoadVSFilter() {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loading VSFilter"));
// Loading an avisynth plugin multiple times does almost nothing
wxFileName vsfilterPath(AegisubApp::folderName + _T("vsfilter.dll"));
if (vsfilterPath.FileExists())
if (vsfilterPath.FileExists()) {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Invoking LoadPlugin"));
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
else {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loaded"));
} else {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: VSFilter.dll not found in Aegisub dir, trying to locate registered DShow filter"));
wxRegKey reg(_T("HKEY_CLASSES_ROOT\\CLSID\\{9852A670-F845-491B-9BE6-EBD841B8A613}\\InprocServer32"));
if (reg.Exists()) {
wxString fn;
@ -313,15 +371,19 @@ void AvisynthVideoProvider::LoadVSFilter() {
vsfilterPath = fn;
if (vsfilterPath.FileExists()) {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Found as DShow filter, loading"));
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Loaded"));
return;
}
vsfilterPath = _T("vsfilter.dll");
} else if (vsfilterPath.FileExists())
env->Invoke("LoadPlugin",env->SaveString(vsfilterPath.GetFullPath().mb_str(wxConvLocal)));
else if (!env->FunctionExists("TextSub"))
else if (!env->FunctionExists("TextSub")) {
AVSTRACE(_T("AvisynthVideoProvider::LoadVSFilter: Couldn't locate VSFilter"));
throw _T("Couldn't locate VSFilter");
}
}
}