View Full Version : Programatically detecting script errors
ryaowe
8th August 2008, 15:52
I'm using AVISynth to do some pre-processing of video before I pass it off to an encoder.
This is all automated and done in C code. I'm using the VFW AVIFile API to read the data generated by the AVISynth script.
The problem I have is that when an error occurs within AVISynth, I still get video frames, but they contain the error message instead of my video.
Is there any way for my program to know that there was an error and what it was?
The only idea I've had so far is to use a try...catch in my AVISynth script, and have the catch clause output nothing. That way if there is an error, my C code can tell because it looks like it gets an empty AVI file. But then it doesn't know what the error was.
I guess I could have the catch clause output a single frame with the error in it, or something like that.
Does anyone have any better ideas?
Sagekilla
8th August 2008, 16:01
I'd recommend reading into the Avisynth source code and looking for the code that outputs the error codes as a video frame, and have it pass it off to your C program instead of to the video frame.
ryaowe
8th August 2008, 16:09
Thanks, I'll look into that. I also found a thread (http://forum.doom9.org/showthread.php?t=131674) about using the AVISynth C API to read a clip. Maybe I should be using that instead of the VFW API.
Gavino
8th August 2008, 16:42
I also found a thread (http://forum.doom9.org/showthread.php?t=131674) about using the AVISynth C API to read a clip. Maybe I should be using that instead of the VFW API.
Note that the description given in that thread is specifically about the C API rather than the standard C++ API which is easier to use.
But yes, I think your solution is to use the API one way or the other. I suggest you keep the try...catch approach and in the catch clause just return the error message. In your calling code you can test whether the script returns a clip (good) or a string (error message).
ryaowe
8th August 2008, 17:09
You're right, the C++ API is easier. I just found a thread (http://forum.doom9.org/archive/index.php/t-103195.html) that covers that as well. Thanks for all the help!
IanB
9th August 2008, 00:31
Also you could use the "IID_IAvisynthClipInfo" interface that VirtualDub uses, see AVIReadHandler.cpp in the VirtualDub source.extern "C" const GUID IID_IAvisynthClipInfo // {E6D6B708-124D-11D4-86F3-DB80AFD98778}
= {0xe6d6b708, 0x124d, 0x11d4, {0x86, 0xf3, 0xdb, 0x80, 0xaf, 0xd9, 0x87, 0x78}};
struct IAvisynthClipInfo : IUnknown {
virtual int __stdcall GetError(const char** ppszMessage) = 0;
virtual bool __stdcall GetParity(int n) = 0;
virtual bool __stdcall IsFieldBased() = 0;
};
-----------------------------
paf->QueryInterface(IID_IAvisynthClipInfo, (void **)&pAvisynthClipInfo)
-----------------------------
hr = AVIStreamRead(pas, (LONG)lStart, lSamples, lpBuffer, cbBuffer, plBytes, plSamples);
if (pAvisynthClipInfo) {
const char *pszErr;
if (pAvisynthClipInfo->GetError(&pszErr))
printf("Avisynth read error:\n%s", pszErr);
}
}
ianken
25th October 2011, 23:53
I know this thread is ancient. But I'm looking at the same issue and getting a failure to QI for IID_IAvisynthClipInfo
The project is dShow. But I want to use some VfW calls to pull out the error text without having to link in the AVS sdk bits.
I've spelunked both the AVs source and VDub and both seem to indicate that this is teh way to do it...
GUID CLSID_Avisynth = {0xE6D6B700, 0x124D, 0x11D4, 0x86, 0xF3, 0xDB, 0x80, 0xAF, 0xD9, 0x87, 0x78};
GUID IID_IAvisynthClipInfo = {0xe6d6b708, 0x124d, 0x11d4, 0x86, 0xf3, 0xdb, 0x80, 0xaf, 0xd9, 0x87, 0x78};
AVIFILEINFO fileinfo;
IAVIFile *pAVIFile = NULL;
const char *ErrorString;
IAvisynthClipInfo *clipInfo;
hr = AVIFileOpen(&pAVIFile,lpwstrFile,OF_READ, NULL);
if FAILED(hr) return hr;
hr = pAVIFile->QueryInterface(IID_IAvisynthClipInfo, (void **)&clipInfo);
if FAILED(hr) return hr;
clipInfo->GetError(&ErrorString);
I've got the IIDs right (pulled from the AVS source) but the QI bails with "E_NOINTERFACE." I assume I'm making some total newb mistake...
Debug spew:
DllGetClassObject() CLSID: CAVIFileSynth
006445E0->CAVIFileSynth::CAVIFileSynth()
006445E0->CAVIFileSynth::AddRef() gRefCnt=1, m_refs=1
006445E0->CAVIFileSynth::QueryInterface() {00000001-0000-0000-c000-000000000046} (IClassFactory)
006445E0->CAVIFileSynth::AddRef() gRefCnt=2, m_refs=2
006445E0->CAVIFileSynth::Release() gRefCnt=1, m_refs=1
DllGetClassObject() result=0x0, object=006445E8
006445E0->CAVIFileSynth::CreateInstance()
00644638->CAVIFileSynth::CAVIFileSynth()
00644638->CAVIFileSynth::AddRef() gRefCnt=2, m_refs=1
00644638->CAVIFileSynth::QueryInterface() {00000000-0000-0000-c000-000000000046} (IUnknown)
00644638->CAVIFileSynth::AddRef() gRefCnt=3, m_refs=2
00644638->CAVIFileSynth::Release() gRefCnt=2, m_refs=1
006445E0->CAVIFileSynth::CreateInstance() result=0x0, object=00644638
00644638->CAVIFileSynth::AddRef() gRefCnt=3, m_refs=2
00644638->CAVIFileSynth::Release() gRefCnt=2, m_refs=1
006445E0->CAVIFileSynth::Release() gRefCnt=1, m_refs=0
006445E0->CAVIFileSynth::~CAVIFileSynth(), gRefCnt = 1
00644638->CAVIFileSynth::QueryInterface() {00000003-0000-0000-c000-000000000046} (unsupported!)
00644638->CAVIFileSynth::QueryInterface() {0000001b-0000-0000-c000-000000000046} (unsupported!)
00644638->CAVIFileSynth::QueryInterface() {00000000-0000-0000-c000-000000000046} (IUnknown)
00644638->CAVIFileSynth::AddRef() gRefCnt=2, m_refs=2
00644638->CAVIFileSynth::AddRef() gRefCnt=3, m_refs=3
00644638->CAVIFileSynth::QueryInterface() {00000018-0000-0000-c000-000000000046} (unsupported!)
00644638->CAVIFileSynth::QueryInterface() {00000019-0000-0000-c000-000000000046} (unsupported!)
00644638->CAVIFileSynth::QueryInterface() {4c1e39e1-e3e3-4296-aa86-ec938d896e92} (unsupported!)
00644638->CAVIFileSynth::Release() gRefCnt=2, m_refs=2
00644638->CAVIFileSynth::Release() gRefCnt=1, m_refs=1
00644638->CAVIFileSynth::QueryInterface() {00020025-0000-0000-c000-000000000046} (unsupported!)
00644638->CAVIFileSynth::QueryInterface() {0000010b-0000-0000-c000-000000000046} (IPersistFile)
00644638->CAVIFileSynth::AddRef() gRefCnt=2, m_refs=2
00644638->CAVIFileSynth::QueryInterface() {0000010b-0000-0000-c000-000000000046} (IPersistFile)
00644638->CAVIFileSynth::AddRef() gRefCnt=3, m_refs=3
00644638->CAVIFileSynth::QueryInterface() {00020020-0000-0000-c000-000000000046} (IAVIFile)
00644638->CAVIFileSynth::AddRef() gRefCnt=4, m_refs=4
00644638->CAVIFileSynth::QueryInterface() {00020020-0000-0000-c000-000000000046} (IAVIFile)
00644638->CAVIFileSynth::AddRef() gRefCnt=5, m_refs=5
00644638->CAVIFileSynth::QueryInterface() {1c733a30-2a1c-11ce-ade5-00aa0044773d} (unsupported!)
00644638->CAVIFileSynth::Load("D:\Convert\FromDShow.avs", 0x0)
00644638->CAVIFileSynth::QueryInterface() {e6d6b708-124d-11d4-86f3-db80afd98778} (IAvisynthClipInfo)
00644638->CAVIFileSynth::AddRef() gRefCnt=6, m_refs=6
00644638->CAVIFileSynth::Release() gRefCnt=5, m_refs=5
IanB
26th October 2011, 01:21
The code you have included looks okay.
The open loaded the script and the QueryInterface returned the object.
Need a bit more information to understand your issue :confused:
00644638->CAVIFileSynth::Load("D:\Convert\FromDShow.avs", 0x0)
00644638->CAVIFileSynth::QueryInterface() {e6d6b708-124d-11d4-86f3-db80afd98778} (IAvisynthClipInfo)
00644638->CAVIFileSynth::AddRef() gRefCnt=6, m_refs=6
The AVisynth code on the other side that wrote the log messages is this :-STDMETHODIMP CAVIFileSynth::QueryInterface(const IID& iid, void **ppv) {
if (!ppv) {
_RPT1(0,"%p->CAVIFileSynth::QueryInterface() E_POINTER\n", this);
return E_POINTER;
}
_RPT1(0,"%p->CAVIFileSynth::QueryInterface() ", this);
_RPT3(0,"{%08lx-%04x-%04x-", iid.Data1, iid.Data2, iid.Data3);
_RPT4(0,"%02x%02x-%02x%02x", iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3]);
_RPT4(0,"%02x%02x%02x%02x} (", iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]);
if (iid == IID_IUnknown) {
*ppv = (IUnknown *)(IAVIFile *)this;
_RPT0(0,"IUnknown)\n");
} else if (iid == IID_IClassFactory) {
*ppv = (IClassFactory *)this;
_RPT0(0,"IClassFactory)\n");
} else if (iid == IID_IPersist) {
*ppv = (IPersist *)this;
_RPT0(0,"IPersist)\n");
} else if (iid == IID_IPersistFile) {
*ppv = (IPersistFile *)this;
_RPT0(0,"IPersistFile)\n");
} else if (iid == IID_IAVIFile) {
*ppv = (IAVIFile *)this;
_RPT0(0,"IAVIFile)\n");
} else if (iid == IID_IAvisynthClipInfo) {
*ppv = (IAvisynthClipInfo *)this;
_RPT0(0,"IAvisynthClipInfo)\n");
} else {
_RPT0(0,"unsupported!)\n");
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ianken
26th October 2011, 04:00
Turns out I had my threading model borked and it couldn't marshal the QI.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.