bwkahle
9th August 2011, 22:49
I'm running 2 STA threads each with its own instance of a WMV VC-1 encoder. The encoders are using an Avisynth script as the input file and opened using the AVIFile functions.
The encoders will run in tandem just fine for some variable period of time before causing an access violation. I've traced the problem to avisynth trying to use the same VideoFrame object for both threads
Below are the truncated stack traces for both threads.
avisynth.dll!FilteredResizeH::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 1108 C++
> avisynth.dll!Cache::childGetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 399 + 0x15 bytes C++
avisynth.dll!ConvertToYV12::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 233 + 0x33 bytes C++
avisynth.dll!Cache::childGetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 399 + 0x15 bytes C++
avisynth.dll!CAVIStreamSynth::ReadFrame(void * lpBuffer=0x0f840020, int n=428) Line 995 + 0x3c bytes C++
avisynth.dll!CAVIStreamSynth::ReadHelper(void * lpBuffer=0x0f840020, int lStart=428, int lSamples=-1, unsigned int * code=0x078dece0) Line 1063 C++
avisynth.dll!CAVIStreamSynth::Read2(long lStart=428, long lSamples=-1, void * lpBuffer=0x0f840020, long cbBuffer=613440, long * plBytes=0x078defe0, long * plSamples=0x00000000) Line 1289 C++
avisynth.dll!CAVIStreamSynth::Read(long lStart=428, long lSamples=-1, void * lpBuffer=0x0f840020, long cbBuffer=613440, long * plBytes=0x078defe0, long * plSamples=0x00000000) Line 1180 + 0x20 bytes C++
avifil32.dll!_AVIStreamRead@28() + 0x20 bytes
avisynth.dll!FilteredResizeH::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 1108 C++
avisynth.dll!Cache::childGetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 399 + 0x15 bytes C++
avisynth.dll!ConvertToYV12::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 233 + 0x33 bytes C++
avisynth.dll!Cache::childGetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 399 + 0x15 bytes C++
avisynth.dll!CAVIStreamSynth::ReadFrame(void * lpBuffer=0x0c4c0020, int n=110) Line 995 + 0x3c bytes C++
avisynth.dll!CAVIStreamSynth::ReadHelper(void * lpBuffer=0x0c4c0020, int lStart=110, int lSamples=-1, unsigned int * code=0x076fe720) Line 1063 C++
avisynth.dll!CAVIStreamSynth::Read2(long lStart=110, long lSamples=-1, void * lpBuffer=0x0c4c0020, long cbBuffer=613440, long * plBytes=0x076fea20, long * plSamples=0x00000000) Line 1289 C++
avisynth.dll!CAVIStreamSynth::Read(long lStart=110, long lSamples=-1, void * lpBuffer=0x0c4c0020, long cbBuffer=613440, long * plBytes=0x076fea20, long * plSamples=0x00000000) Line 1180 + 0x20 bytes C++
avifil32.dll!_AVIStreamRead@28() + 0x20 bytes
Inside FilteredResizeH::GetFrame dst->GetWritePtr() is returning a null pointer because VideoFrame::refcount == 2
Both threads are referencing the same VideoFrame object at 0x085e40cc. This object is returned from IScriptEnvironment::NewVideoFrame on the 2nd line of FilteredResizeH::GetFrame.
How is it possible both threads get the same VideoFrame object back from NewVideoFrame()? Is this a bug or intended behavior?
I have a full debug environment setup if more information is needed.
The encoders will run in tandem just fine for some variable period of time before causing an access violation. I've traced the problem to avisynth trying to use the same VideoFrame object for both threads
Below are the truncated stack traces for both threads.
avisynth.dll!FilteredResizeH::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 1108 C++
> avisynth.dll!Cache::childGetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 399 + 0x15 bytes C++
avisynth.dll!ConvertToYV12::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 233 + 0x33 bytes C++
avisynth.dll!Cache::childGetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=428, IScriptEnvironment * env=0x0860a7d0) Line 399 + 0x15 bytes C++
avisynth.dll!CAVIStreamSynth::ReadFrame(void * lpBuffer=0x0f840020, int n=428) Line 995 + 0x3c bytes C++
avisynth.dll!CAVIStreamSynth::ReadHelper(void * lpBuffer=0x0f840020, int lStart=428, int lSamples=-1, unsigned int * code=0x078dece0) Line 1063 C++
avisynth.dll!CAVIStreamSynth::Read2(long lStart=428, long lSamples=-1, void * lpBuffer=0x0f840020, long cbBuffer=613440, long * plBytes=0x078defe0, long * plSamples=0x00000000) Line 1289 C++
avisynth.dll!CAVIStreamSynth::Read(long lStart=428, long lSamples=-1, void * lpBuffer=0x0f840020, long cbBuffer=613440, long * plBytes=0x078defe0, long * plSamples=0x00000000) Line 1180 + 0x20 bytes C++
avifil32.dll!_AVIStreamRead@28() + 0x20 bytes
avisynth.dll!FilteredResizeH::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 1108 C++
avisynth.dll!Cache::childGetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 399 + 0x15 bytes C++
avisynth.dll!ConvertToYV12::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 233 + 0x33 bytes C++
avisynth.dll!Cache::childGetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 236 + 0x33 bytes C++
avisynth.dll!Cache::GetFrame(int n=110, IScriptEnvironment * env=0x085e41f8) Line 399 + 0x15 bytes C++
avisynth.dll!CAVIStreamSynth::ReadFrame(void * lpBuffer=0x0c4c0020, int n=110) Line 995 + 0x3c bytes C++
avisynth.dll!CAVIStreamSynth::ReadHelper(void * lpBuffer=0x0c4c0020, int lStart=110, int lSamples=-1, unsigned int * code=0x076fe720) Line 1063 C++
avisynth.dll!CAVIStreamSynth::Read2(long lStart=110, long lSamples=-1, void * lpBuffer=0x0c4c0020, long cbBuffer=613440, long * plBytes=0x076fea20, long * plSamples=0x00000000) Line 1289 C++
avisynth.dll!CAVIStreamSynth::Read(long lStart=110, long lSamples=-1, void * lpBuffer=0x0c4c0020, long cbBuffer=613440, long * plBytes=0x076fea20, long * plSamples=0x00000000) Line 1180 + 0x20 bytes C++
avifil32.dll!_AVIStreamRead@28() + 0x20 bytes
Inside FilteredResizeH::GetFrame dst->GetWritePtr() is returning a null pointer because VideoFrame::refcount == 2
Both threads are referencing the same VideoFrame object at 0x085e40cc. This object is returned from IScriptEnvironment::NewVideoFrame on the 2nd line of FilteredResizeH::GetFrame.
How is it possible both threads get the same VideoFrame object back from NewVideoFrame()? Is this a bug or intended behavior?
I have a full debug environment setup if more information is needed.