changeset 713:9355b2ae634e

avifile-0.6-CVS merge
author arpi_esp
date Sun, 06 May 2001 21:43:45 +0000
parents ea093aa3ecae
children eb58bada8bce
files DOCS/codecs.conf dll_init.c loader/dshow/DS_Filter.c loader/dshow/DS_Filter.h loader/dshow/DS_VideoDec.c loader/dshow/allocator.c loader/dshow/allocator.h loader/dshow/cmediasample.c loader/dshow/cmediasample.h loader/dshow/guids.c loader/dshow/interfaces.h loader/dshow/outputpin.c loader/dshow/outputpin.h loader/stubs.s loader/win32.c
diffstat 15 files changed, 329 insertions(+), 158 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/codecs.conf	Sun May 06 19:38:57 2001 +0000
+++ b/DOCS/codecs.conf	Sun May 06 21:43:45 2001 +0000
@@ -9,6 +9,7 @@
   comment "with postprocessing"
   status working
   format 0x1
+  format 0xFFFFFF01
   driver libmpeg2
   dll "libmpeg2"
   out YV12
@@ -151,7 +152,7 @@
   out UYVY
   out BGR32,BGR24,BGR15
 
-videocodec wmv1
+videocodec wmv7
   info "Windows Media Video 7"
   status working
   fourcc WMV1
@@ -162,6 +163,17 @@
   out YUY2
   out BGR32,BGR24,BGR16,BGR15
 
+videocodec wmv8
+  info "Windows Media Video 8"
+  status crashing
+  comment "Floating point exception"
+  fourcc WMV2
+  driver dshow
+  dll "wmv8ds32.ax"
+  guid 0x521fb373, 0x7654, 0x49f2, 0xbd, 0xb1, 0x0c, 0x6e, 0x66, 0x60, 0x71, 0x4f
+  out YUY2
+  out BGR32,BGR24,BGR16,BGR15
+
 videocodec ap41
   info "AngelPotion Definitive V1"	; yet another stolen stuff
   comment "using the DivX ;-) codec"
@@ -176,7 +188,7 @@
 videocodec tm20
   info "TrueMotion 2.0"
   status crashing
-  comment "Error connecting to output pin"
+  comment "segfault in the DLL"
   fourcc TM20
   driver dshow
   dll "tm20dec.ax"
@@ -248,15 +260,6 @@
   out YUY2
   out BGR32,BGR24,BGR15
 
-videocodec wmv8
-  info "Windows Media Video 8"
-  status untested
-  fourcc WMV2
-  driver dshow
-  dll "wmv8ds32.ax"
-  guid 0x521fb373, 0x7654, 0x49f2, 0xbd, 0xb1, 0x0c, 0x6e, 0x66, 0x60, 0x71, 0x4f
-;  out YUY2
-  out BGR32,BGR24,BGR16,BGR15
 
 videocodec m261
   info "M261"
@@ -274,7 +277,18 @@
   driver vfw
   dll "asusasv2.dll"
 ;  out YVYU
-  out UYVY flip
+  out UYVY
+  out BGR32,BGR24,BGR15 flip
+
+videocodec asv1
+  info "ASUS V1"
+  status buggy
+  comment "rgb upside down, yuv ok"
+  fourcc ASV1
+  driver vfw
+  dll "asusasvd.dll"
+;  out YVYU
+  out UYVY
   out BGR32,BGR24,BGR15 flip
 
 ;=============================================================================
@@ -300,7 +314,7 @@
 audiocodec mp3acm
   info "MPEG layer-3"
   status working
-  comment "Optimized to Intel MMX/SSE"
+  comment "Optimized to Intel MMX/SSE, conflicts with security kernel patches"
   format 0x55
   driver acm
   dll "l3codeca.acm"
--- a/dll_init.c	Sun May 06 19:38:57 2001 +0000
+++ b/dll_init.c	Sun May 06 21:43:45 2001 +0000
@@ -166,6 +166,12 @@
 //  sh_video->o_bih.biPlanes=3;
 //  sh_video->o_bih.biBitCount=16;
 
+#if 0
+  // workaround for pegasus MJPEG:
+  if(!sh_video->o_bih.biWidth) sh_video->o_bih.biWidth=sh_video->bih->biWidth;
+  if(!sh_video->o_bih.biHeight) sh_video->o_bih.biHeight=sh_video->bih->biHeight;
+  if(!sh_video->o_bih.biPlanes) sh_video->o_bih.biPlanes=sh_video->bih->biPlanes;
+#endif
 
   switch (outfmt) {
 
@@ -213,7 +219,15 @@
       return 0;
   }
 
+  printf("XXX w=%d  h=%d  b=%d\n",
+        sh_video->o_bih.biWidth,
+        sh_video->o_bih.biHeight,
+        sh_video->o_bih.biBitCount/8
+  );
+
   sh_video->o_bih.biSizeImage = sh_video->o_bih.biWidth * sh_video->o_bih.biHeight * (sh_video->o_bih.biBitCount/8);
+  
+  printf("XXX size=%d\n",sh_video->o_bih.biSizeImage);
 
   if(!(sh_video->codec->outflags[sh_video->outfmtidx]&CODECS_FLAG_FLIP)) {
       sh_video->o_bih.biHeight=-sh_video->bih->biHeight; // flip image!
@@ -248,6 +262,7 @@
   }
   if(verbose) printf("ICDecompressQuery OK\n");
 
+  printf("XXX size=%d\n",sh_video->o_bih.biSizeImage);
   
   ret = ICDecompressBegin(sh_video->hic, sh_video->bih, &sh_video->o_bih);
   if(ret){
@@ -255,6 +270,8 @@
     return 0;
   }
 
+  printf("XXX size=%d\n",sh_video->o_bih.biSizeImage);
+
 #if 0
 
 //sh_video->hic
--- a/loader/dshow/DS_Filter.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/DS_Filter.c	Sun May 06 21:43:45 2001 +0000
@@ -4,6 +4,7 @@
 #include <except.h>
 //#include "../loader/loader.h"
 #include <string>
+#include <iostream>
 #define __MODULE__ "DirectShow generic filter"
 
 using namespace std;
@@ -12,7 +13,6 @@
 extern "C" char* def_path;
 
 extern "C" int STDCALL expLoadLibraryA(const char*);
-//extern "C" int WINAPI expLoadLibraryA(char* name);
 extern "C" STDCALL void* GetProcAddress(int, const char*);
 extern "C" int STDCALL FreeLibrary(int);
 
@@ -21,13 +21,51 @@
 
 DS_Filter::DS_Filter()
     :m_iHandle(0), m_pFilter(0), m_pInputPin(0),
-	m_pOutputPin(0), m_pSrcFilter(0), 
-	m_pOurInput(0), m_pOurOutput(0),
-	m_pImp(0), m_pAll(0), m_pParentFilter(0)
+    m_pOutputPin(0), m_pSrcFilter(0), m_pParentFilter(0),
+    m_pOurInput(0), m_pOurOutput(0), m_pAll(0), m_pImp(0),
+    m_iState(0)
 {
 }
 
-void DS_Filter::Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt)
+void DS_Filter::clean()
+{
+    m_iState = 0;
+
+    if (m_pOurInput)
+	m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
+    if (m_pInputPin)
+	m_pInputPin->vt->Disconnect(m_pInputPin);
+    if (m_pOutputPin)
+	m_pOutputPin->vt->Disconnect(m_pOutputPin);
+    if (m_pFilter)
+	m_pFilter->vt->Release((IUnknown*)m_pFilter);
+    if (m_pOutputPin)
+	m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
+    if (m_pInputPin)
+	m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
+    if (m_pImp)
+	m_pImp->vt->Release((IUnknown*)m_pImp);
+
+    delete m_pOurOutput;
+    delete m_pParentFilter;
+    delete m_pSrcFilter;
+
+    // FIXME - we are still leaving few things allocated!
+    if (m_iHandle)
+	FreeLibrary(m_iHandle);
+
+}
+
+DS_Filter::~DS_Filter()
+{
+    //cout << "Destruction of DS_FILTER" << endl;
+    Stop();
+    if (m_iState == 1)
+	clean();
+    //cout << "Destruction of DS_FILTER done" << endl;
+}
+
+void DS_Filter::Create(char*  dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt)
 {
 
     Setup_LDT_Keeper();
@@ -37,40 +75,37 @@
 //	string _fullname=def_path;
 //	_fullname+="/";
 //	_fullname+=dllname;
-//	m_iHandle= LoadLibraryA(_fullname.c_str());
 	m_iHandle= expLoadLibraryA(dllname);
-	if(!m_iHandle)throw FATAL("Could not open DLL");
+	if (!m_iHandle)
+	{
+	    char e[1024];
+	    sprintf(e, "Could not open DirectShow DLL: %s", dllname);
+	    throw FATAL(e);
+	}
         GETCLASS func=(GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject");
-	if(!func)throw FATAL("Illegal or corrupt DLL");
+	if (!func)
+	{
+	    char e[1024];
+	    sprintf(e, "Illegal or corrupt DirectShow DLL: %s", dllname);
+	    throw FATAL(e);
+	}
 
 	HRESULT result;
 	IClassFactory* factory=0;
-	IUnknown* object=0;
-
 	result=func(id, &IID_IClassFactory, (void**)&factory);
 	if(result || (!factory)) throw FATAL("No such class object");;
-        
-//            printf("# factory = %X\n",(unsigned int)factory);
-//            printf("# factory->vt = %X\n",(unsigned int)factory->vt);
-//            printf("# factory->vt->CreateInstance = %X\n",(unsigned int)factory->vt->CreateInstance);
 
-             setup_FS_Segment();
+	setup_FS_Segment();
 
-//            printf("Calling factory->vt->CreateInstance()\n");
-            result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
-//            printf("Calling factory->vt->Release()\n");
-	
-//	result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
-
-//        printf("CreateInstance ok %x\n",result);
-
+	IUnknown* object=0;
+	result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
 	factory->vt->Release((IUnknown*)factory);
 	if(result || (!object)) throw FATAL("Class factory failure");
-	    
+
 	result=object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter);
 	object->vt->Release((IUnknown*)object);
 	if(result || (!m_pFilter)) throw FATAL("Object does not have IBaseFilter interface");
-	
+
 	IEnumPins* enum_pins=0;
     //	enumerate pins
 	result=m_pFilter->vt->EnumPins(m_pFilter, &enum_pins);
@@ -79,109 +114,96 @@
 	ULONG fetched;
 	enum_pins->vt->Reset(enum_pins);
 	result=enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
-//	printf("Pins enumeration returned %d pins, error is %x\n", fetched, result);
-	
-	for(int i=0; i<fetched; i++)
+	Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result);
+
+	for (unsigned i = 0; i < fetched; i++)
 	{
-	    int direction=-1;
+	    int direction = -1;
 	    array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
-	    if((!m_pInputPin)&&(direction==0))
+	    if (!m_pInputPin && direction == 0)
 	    {
-		m_pInputPin=array[i];
+		m_pInputPin = array[i];
 		m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin);
 	    }
-	    if((!m_pOutputPin)&&(direction==1))
+	    if (!m_pOutputPin && direction == 1)
 	    {
-		m_pOutputPin=array[i];
+		m_pOutputPin = array[i];
 		m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin);
 	    }
 	    array[i]->vt->Release((IUnknown*)(array[i]));
 	}
-	if(!m_pInputPin)throw FATAL("Input pin not found");
-	if(!m_pOutputPin)throw FATAL("Output pin not found");
+	if (!m_pInputPin)
+	    throw FATAL("Input pin not found");
+	if (!m_pOutputPin)
+	    throw FATAL("Output pin not found");
 
-	result=m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, &IID_IMemInputPin, (void**)&m_pImp);
+	result = m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin,
+						 &IID_IMemInputPin,
+						 (void**)&m_pImp);
         if(result)
 	    throw FATAL("Error getting IMemInputPin interface");
 	m_pOurType=in_fmt;
 	m_pDestType=out_fmt;
         result=m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType);
-	if(result) throw FATAL("Source format is not accepted");
+	if (result)
+	    throw FATAL("Source format is not accepted");
 
 	m_pParentFilter=new CBaseFilter2;
         m_pSrcFilter=new CBaseFilter(*m_pOurType, m_pParentFilter);
 	m_pOurInput=m_pSrcFilter->GetPin();
 	m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput);
-	
-    	result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput, m_pOurType);
-	if(result) throw FATAL("Error connecting to input pin");
-	
-	m_pOurOutput=new COutputPin(*m_pDestType);
-        result=m_pOutputPin->vt->ReceiveConnection(m_pOutputPin,
-	     m_pOurOutput, m_pDestType);
-	if(result)throw FATAL("Error connecting to output pin");    
-	m_iState=1;
+
+	result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput,
+						  m_pOurType);
+	if (result)
+	    throw FATAL("Error connecting to input pin");
+
+	m_pOurOutput = new COutputPin(*m_pDestType);
+
+	result = m_pOutputPin->vt->ReceiveConnection(m_pOutputPin,
+						     m_pOurOutput,
+						     m_pDestType);
+	if (result)
+	    throw FATAL("Error connecting to output pin");
+	cout << "Using DirectShow codec: " << dllname << endl;
+	m_iState = 1;
     }
     catch(FatalError e)
     {
 	e.PrintAll();
-    	if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
-	if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
-	if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
-	if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
-	if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
-	delete m_pSrcFilter;
-	delete m_pParentFilter;
-	delete m_pOurOutput;
-	if(m_iHandle)FreeLibrary(m_iHandle);
+        clean();
 	throw;
     }
 }
+
 void DS_Filter::Start()
 {
-    if(m_iState!=1)
+    if (m_iState != 1)
 	return;
-    
+
     HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0);
-    if(hr!=0)
+    if (hr != 0)
     {
-	cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl;
+	Debug cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl;
     }
     hr=m_pImp->vt->GetAllocator(m_pImp, &m_pAll);
-    if(hr)
+    if (hr)
     {
-        cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl;
+        Debug cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl;
         m_pImp->vt->Release((IUnknown*)m_pImp);
         return;
     }
     m_pImp->vt->NotifyAllocator(m_pImp, m_pAll,	0);
-    m_iState=2;
-    return;
+    m_iState = 2;
 }
+
 void DS_Filter::Stop()
 {
-    if(m_iState!=2)
-	return;
-    m_pAll->vt->Release((IUnknown*)m_pAll);
-    m_pAll=0;
-    m_pFilter->vt->Stop(m_pFilter);
-    m_iState=1;
-    return;
+    if (m_iState == 2)
+    {
+	m_pAll->vt->Release((IUnknown*)m_pAll);
+	m_pAll=0;
+	m_pFilter->vt->Stop(m_pFilter);
+	m_iState=1;
+    }
 }
-DS_Filter::~DS_Filter()
-{
-    if(m_iState==0)
-	return;
-    if(m_iState==2)Stop();
-    if(m_pInputPin)m_pInputPin->vt->Disconnect(m_pInputPin);
-    if(m_pOutputPin)m_pOutputPin->vt->Disconnect(m_pOutputPin);
-    if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
-    if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
-    if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
-    if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
-    if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
-    delete m_pSrcFilter;
-    delete m_pParentFilter;
-    delete m_pOurOutput;
-    if(m_iHandle)FreeLibrary(m_iHandle);
-}
--- a/loader/dshow/DS_Filter.h	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/DS_Filter.h	Sun May 06 21:43:45 2001 +0000
@@ -5,18 +5,16 @@
 #include "inputpin.h"
 #include "outputpin.h"
 #include <string>
-using namespace std;
+
 /**
     User will allocate and fill format structures, call Create(),
     and then set up m_pAll.
 **/    
 class DS_Filter
 {
-protected:
 public:
     DS_Filter();
     virtual ~DS_Filter();
-    void Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt);
     void Start();
     void Stop();
     int m_iHandle;
@@ -33,8 +31,11 @@
     IMemAllocator* m_pAll;
     IMemInputPin* m_pImp;
     int m_iState;
-protected:
-};    
+
+    void Create(char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt);
+    void SetPointer(char* pointer);
+private:
+    void clean();
+};
 
 #endif
-
--- a/loader/dshow/DS_VideoDec.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/DS_VideoDec.c	Sun May 06 21:43:45 2001 +0000
@@ -79,7 +79,7 @@
 	memset(&m_obh, 0, sizeof(m_obh));
 	m_obh.biSize=sizeof(m_obh);
 
-	memset(&m_sVhdr, 0, sizeof m_sVhdr);
+	memset(&m_sVhdr, 0, sizeof(m_sVhdr));
 	m_sVhdr.bmiHeader=m_bh;
 	m_sVhdr.rcSource.left=m_sVhdr.rcSource.top=0;
 	m_sVhdr.rcSource.right=m_sVhdr.bmiHeader.biWidth;
@@ -93,7 +93,7 @@
         m_sOurType.bFixedSizeSamples=false;
 	m_sOurType.bTemporalCompression=true;
 	m_sOurType.pUnk=0;
-        m_sOurType.cbFormat=sizeof m_sVhdr;
+        m_sOurType.cbFormat=sizeof(m_sVhdr);
         m_sOurType.pbFormat=(char*)&m_sVhdr;
 
 	m_sVhdr2=(VIDEOINFOHEADER*)(new char[sizeof(VIDEOINFOHEADER)+12]);
@@ -101,7 +101,7 @@
 	m_sVhdr2->bmiHeader.biCompression=0;
 	m_sVhdr2->bmiHeader.biBitCount=24;
 
-	memset(&m_sDestType, 0, sizeof m_sDestType);
+	memset(&m_sDestType, 0, sizeof(m_sDestType));
 	m_sDestType.majortype=MEDIATYPE_Video;
 	m_sDestType.subtype=MEDIASUBTYPE_RGB24;
 	m_sDestType.formattype=FORMAT_VideoInfo;
@@ -119,19 +119,20 @@
         
 	HRESULT result;
 
+        dsf=new DS_Filter();
+	dsf->Create(dllname, guid, &m_sOurType, &m_sDestType);
+
 	if(!flip)
 	{
 	    m_sVhdr2->bmiHeader.biHeight*=-1;
 	    m_obh.biHeight*=-1;
-//	    result=m_pOutputPin->vt->QueryAccept(m_pOutputPin, &m_sDestType);
-//	    if(result)
-//		throw FATAL("Decoder does not support upside-down frames");
+	    result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType);
+	    if(result){
+                printf("DShow: Decoder does not support upside-down frames");
+                m_obh.biHeight*=-1;
+            }
 	}	
 
-        dsf=new DS_Filter();
-        
-	dsf->Create(dllname, guid, &m_sOurType, &m_sDestType);
-
 #if 0
 	m_sVhdr2->bmiHeader.biBitCount=16;
 	m_sVhdr2->bmiHeader.biCompression=fccYUY2;
@@ -182,7 +183,7 @@
 extern "C" void DS_VideoDecoder_Stop(){
     if(dsf->m_iState!=2) return;
     dsf->Stop();
-    dsf->m_pOurOutput->SetFramePointer(0);
+//    dsf->m_pOurOutput->SetFramePointer(0);
 //    free(m_outFrame->data());
     //m_outFrame->release();//just in case
     //m_outFrame=0;
--- a/loader/dshow/allocator.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/allocator.c	Sun May 06 21:43:45 2001 +0000
@@ -2,6 +2,8 @@
 #include "allocator.h"
 #include <com.h>
 #define E_NOTIMPL 0x80004001
+using namespace std;
+
 class AllocatorKeeper
 {
 public:
@@ -36,6 +38,9 @@
     props.cBuffers=1;
     props.cbBuffer=65536;/* :/ */
     props.cbAlign=props.cbPrefix=0;
+    
+    new_pointer=0;
+    modified_sample=0;
 }
 
 long MemAllocator::CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
@@ -131,6 +136,14 @@
     me->used_list.push_back(*it);
     *ppBuffer=*it;
     (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
+    if(me->new_pointer)
+    {
+	if(me->modified_sample)
+	    me->modified_sample->ResetPointer();
+        (*it)->SetPointer(me->new_pointer);
+	me->modified_sample=*it;
+	me->new_pointer=0;
+    }
     me->free_list.remove(*it);
     return 0;
 }
--- a/loader/dshow/allocator.h	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/allocator.h	Sun May 06 21:43:45 2001 +0000
@@ -6,19 +6,29 @@
 #include <list>
 #include "iunk.h"
 #include "default.h"
-using namespace std;
+
 class MemAllocator: public IMemAllocator
 {
     ALLOCATOR_PROPERTIES props;
-    list<CMediaSample*> used_list;
-    list<CMediaSample*> free_list;
+    std::list<CMediaSample*> used_list;
+    std::list<CMediaSample*> free_list;
+    char* new_pointer;
+    CMediaSample* modified_sample;
     static GUID interfaces[];
     DECLARE_IUNKNOWN(MemAllocator)
 public:
     MemAllocator();
     ~MemAllocator(){delete vt;}
     static long CreateAllocator(GUID* clsid, GUID* iid, void** ppv);
-
+    void SetPointer(char* pointer) { new_pointer=pointer; }
+    void ResetPointer() 
+    { 
+	if(modified_sample) 
+	{
+	    modified_sample->ResetPointer(); 
+	    modified_sample=0;
+	}
+    }
     static HRESULT STDCALL SetProperties ( 
         IMemAllocator * This,
         /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
--- a/loader/dshow/cmediasample.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/cmediasample.c	Sun May 06 21:43:45 2001 +0000
@@ -33,12 +33,15 @@
     isPreroll=0;
     type_valid=0;
     block=new char[size];    
+    old_block=0;
     Debug printf("%x: Creating media sample with size %d, buffer 0x%x\n", this, _size, block);
 }
 CMediaSample::~CMediaSample()
 {
     Debug printf("%x: CMediaSample::~CMediaSample() called\n", this);
     delete vt;
+    if(old_block)
+	block=old_block;
     delete[] block;
     if(media_type.pbFormat)
 	CoTaskMemFree(media_type.pbFormat);
--- a/loader/dshow/cmediasample.h	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/cmediasample.h	Sun May 06 21:43:45 2001 +0000
@@ -10,6 +10,7 @@
     int size;
     int actual_size;
     char* block;
+    char* old_block;
     int refcount;
     int isPreroll;
     int isSyncPoint;
@@ -18,6 +19,8 @@
 public:
     CMediaSample(IMemAllocator* allocator, long _size);
     ~CMediaSample();
+    void SetPointer(char* pointer) { old_block=block; block=pointer; }
+    void ResetPointer() { block=old_block; old_block=0; }
 
     static long STDCALL QueryInterface ( 
         IUnknown * This,
--- a/loader/dshow/guids.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/guids.c	Sun May 06 21:43:45 2001 +0000
@@ -55,7 +55,6 @@
 GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0,
     {0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}};
 GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2,
-    {0xa1, 0xc1, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa
-}};
+    {0xa1, 0xc1, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}};
 GUID IID_Iv50Hidden={0x665a4442, 0xd905, 0x11d0,
     {0xa3, 0x0e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
--- a/loader/dshow/interfaces.h	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/interfaces.h	Sun May 06 21:43:45 2001 +0000
@@ -415,4 +415,3 @@
     struct IHidden2_vt *vt;
 };
 #endif
-
--- a/loader/dshow/outputpin.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/outputpin.c	Sun May 06 21:43:45 2001 +0000
@@ -1,8 +1,11 @@
+
+#include <cstdio>
+#include <string>
+
 #include "outputpin.h"
-#include <string.h>
-#include <stdio.h>
 #include "allocator.h"
 #include "iunk.h"
+
 #define E_NOTIMPL 0x80004001
 /*
     An object beyond interface IEnumMediaTypes.
@@ -112,7 +115,7 @@
 
 COutputPin::COutputPin(const AM_MEDIA_TYPE& vh) :refcount(1), type(vh), remote(0), frame_pointer(0), frame_size_pointer(0)
 {
-    IPin::vt=new IPin_vt;
+    IPin::vt = new IPin_vt;
     IPin::vt->QueryInterface = QueryInterface;
     IPin::vt->AddRef = AddRef;
     IPin::vt->Release = Release;
@@ -142,6 +145,15 @@
     IMemInputPin::vt->Receive = Receive;
     IMemInputPin::vt->ReceiveMultiple = ReceiveMultiple;
     IMemInputPin::vt->ReceiveCanBlock = ReceiveCanBlock;
+    
+    pAllocator = 0;
+    frame_pointer = 0;
+}
+
+COutputPin::~COutputPin()
+{
+    delete IPin::vt;
+    delete IMemInputPin::vt;
 }
 
 // IPin->IUnknown methods
@@ -164,19 +176,22 @@
     }
 
     Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" \
-			"%02x%02x%02x%02x%02x%02x\n",
-	 iid->f1,  iid->f2,  iid->f3,
-    	 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
-	(unsigned char)iid->f4[2],(unsigned char)iid->f4[3],(unsigned char)iid->f4[4],	  
-	(unsigned char)iid->f4[5],(unsigned char)iid->f4[6],(unsigned char)iid->f4[7]);
+		 "%02x%02x%02x%02x%02x%02x\n",
+		 iid->f1,  iid->f2,  iid->f3,
+		 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
+		 (unsigned char)iid->f4[2], (unsigned char)iid->f4[3],
+		 (unsigned char)iid->f4[4], (unsigned char)iid->f4[5],
+		 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]);
     return 0x80004002;
 }
+
 HRESULT STDCALL COutputPin::AddRef(IUnknown* This)
 {
     Debug printf("COutputPin::AddRef() called\n");
     ((COutputPin*)This)->refcount++;
     return 0;
 }
+
 HRESULT STDCALL COutputPin::Release(IUnknown* This)
 {
     Debug printf("COutputPin::Release() called\n");
@@ -278,7 +293,6 @@
     return E_NOTIMPL;
 }
 
-
 HRESULT STDCALL COutputPin::QueryAccept ( 
     IPin * This,
     /* [in] */ const AM_MEDIA_TYPE *pmt)
@@ -426,6 +440,8 @@
     /* [in] */ int bReadOnly)
 {
     Debug printf("COutputPin::NotifyAllocator() called\n");
+    COutputPin* pPin=(COutputPin*)This;
+    pPin->pAllocator=(MemAllocator*)pAllocator;
     return 0;
 }
 
@@ -450,7 +466,8 @@
     int len=pSample->vt->GetActualDataLength(pSample);
     if(len==0)len=pSample->vt->GetSize(pSample);//for iv50
     //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len);
-    *me.frame_pointer=pointer;
+    if(me.frame_pointer)
+	*me.frame_pointer=pointer;
     if(me.frame_size_pointer)*me.frame_size_pointer=len;
 /*
     FILE* file=fopen("./uncompr.bmp", "wb");
--- a/loader/dshow/outputpin.h	Sun May 06 19:38:57 2001 +0000
+++ b/loader/dshow/outputpin.h	Sun May 06 21:43:45 2001 +0000
@@ -5,7 +5,7 @@
 #include "interfaces.h"
 #include "guids.h"
 #include "default.h"
-
+#include "allocator.h"
 class COutputPin: public IPin, public IMemInputPin
 {
     int refcount;
@@ -13,10 +13,12 @@
     IPin* remote;
     char** frame_pointer;
     long* frame_size_pointer;
+    MemAllocator* pAllocator;
 public:
     COutputPin(const AM_MEDIA_TYPE& vhdr);
-    ~COutputPin(){delete IPin::vt; delete IMemInputPin::vt;}
+    ~COutputPin();
     void SetFramePointer(char** z){frame_pointer=z;}
+    void SetPointer2(char* p) { if(pAllocator) pAllocator->SetPointer(p); }
     void SetFrameSizePointer(long* z){frame_size_pointer=z;}
     void SetNewFormat(const AM_MEDIA_TYPE& a){type=a;}
     static HRESULT STDCALL QueryInterface(IUnknown* This, GUID* iid, void** ppv);
--- a/loader/stubs.s	Sun May 06 19:38:57 2001 +0000
+++ b/loader/stubs.s	Sun May 06 21:43:45 2001 +0000
@@ -1,10 +1,10 @@
 	.file	"stubs.c"
-	.version	"01.01"
+	.version  "01.01"
 gcc2_compiled.:
 .section	.rodata
 .LC0:
 	.string	"Called unk_%s\n"
-.text
+.data
 	.align 4
 .globl unk_exp1
 	.type	 unk_exp1,@function
--- a/loader/win32.c	Sun May 06 19:38:57 2001 +0000
+++ b/loader/win32.c	Sun May 06 21:43:45 2001 +0000
@@ -1577,6 +1577,26 @@
 {
     char qq[256];
     int result;
+    char* lastbc;
+    if (!name)
+	return -1;
+    // we skip to the last backslash
+    // this is effectively eliminating weird characters in
+    // the text output windows
+    lastbc = strrchr(name, '\\');
+    if (lastbc)
+    {
+        int i;
+        lastbc++;
+	for (i = 0; 1 ;i++)
+	{
+	    name[i] = *lastbc++;
+	    if (!name[i])
+		break;
+	}
+    }
+//    printf("LoadLibrary wants: %s/%s\n", def_path, name);
+
     if(strncmp(name, "c:\\windows\\", 11)==0)name+=11;
     if(name[0]!='/')
     {
@@ -1848,10 +1868,10 @@
     dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
     return result; 
 }
-void *expstrcpy(char* str1, const char* str2) 
+int expstrcpy(char* str1, const char* str2) 
 {
-    void *result=strcpy(str1, str2);
-    dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
+    int result= (int) strcpy(str1, str2);
+    dbgprintf("strcpy(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
     return result;
 }
 int expstrcmp(const char* str1, const char* str2)
@@ -1860,17 +1880,23 @@
     dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
     return result;
 }
-void *expstrcat(char* str1, const char* str2)
+int expstrcat(char* str1, const char* str2) 
 {
-    void *result=strcat(str1, str2);
-    dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
+    int result= (int) strcat(str1, str2);
+    dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
     return result;    
 }
-void *expmemmove(void* dest, void* src, int n) 
+int expisalnum(int c)
 {
-    void *result=memmove(dest, src, n);
-    dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
-    return memmove;
+    int result= (int) isalnum(c);
+    dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
+    return result;    
+}
+int expmemmove(void* dest, void* src, int n) 
+{
+    int result= (int) memmove(dest, src, n);
+    dbgprintf("memmove(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
+    return result;
 }
 int expmemcmp(void* dest, void* src, int n) 
 {
@@ -1916,6 +1942,16 @@
     if(string)wch_print(string);
     return result;
 }    
+
+int WINAPI expIsBadStringPtrA(const char* string, int nchars)
+{
+    int result;
+//    if(string==0)result=1; else result=0;
+//    dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
+//    if(string)wch_print(string);
+    return result;
+}    
+
 extern long WINAPI InterlockedExchangeAdd( long* dest, long incr )
 {
     long ret;
@@ -2354,6 +2390,45 @@
 }
  
 
+#if 0
+INT WINAPI expMulDiv(int nNumber,int nNumerator,int nDenominator)
+{
+	return ((long long)nNumber * (long long)nNumerator) / nDenominator;
+}
+#endif
+
+int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
+{
+    static const long long max_int=0x7FFFFFFFLL;
+    static const long long min_int=-0x80000000LL;
+    long long tmp=(long long)nNumber*(long long)nNumerator;
+    if(!nDenominator)return 1;
+    tmp/=nDenominator;
+    if(tmp<min_int) return 1;
+    if(tmp>max_int) return 1;
+    return (int)tmp;
+}
+
+LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
+{
+    LONG result=strcasecmp(str1, str2);
+    dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
+    return result;
+}
+
+LONG WINAPI explstrlenA(const char* str1)
+{
+    LONG result=strlen(str1);
+    dbgprintf("strlen(0x%x='%s') => %d\n", str1, str1, result);
+    return result;
+}
+
+LONG WINAPI explstrcpyA(char* str1, const char* str2)
+{
+    int result= (int) strcpy(str1, str2);
+    dbgprintf("strcpy(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
+    return result;
+}
 
 LONG WINAPI expInterlockedExchange(long *dest, long l)
 {
@@ -2363,15 +2438,6 @@
 	return retval;
 }
 
-INT WINAPI expMulDiv(int nNumber,int nNumerator,int nDenominator)
-{
-	return ((long long)nNumber * (long long)nNumerator) / nDenominator;
-}
-
-
-
-
-
 struct exports
 {
     char name[64];
@@ -2392,6 +2458,7 @@
 FF(IsBadWritePtr, 357)
 FF(IsBadReadPtr, 354)
 FF(IsBadStringPtrW, -1)
+FF(IsBadStringPtrA, -1)
 FF(DisableThreadLibraryCalls, -1)
 FF(CreateThread, -1)
 FF(CreateEventA, -1)
@@ -2497,6 +2564,9 @@
 FF(GetProcessAffinityMask, -1)
 FF(InterlockedExchange, -1)
 FF(MulDiv, -1)
+FF(lstrcmpiA, -1)
+FF(lstrlenA, -1)
+FF(lstrcpyA, -1)
 };
 
 struct exports exp_msvcrt[]={
@@ -2512,9 +2582,9 @@
 FF(strcpy, -1)
 FF(strcmp, -1)
 FF(strcat, -1)
+FF(isalnum, -1)
 FF(memmove, -1)
 FF(memcmp, -1)
-//FF(memcpy, -1)
 FF(time, -1)
 };
 struct exports exp_winmm[]={