changeset 3059:24fa494bedb1

imported from xine
author arpi
date Wed, 21 Nov 2001 23:42:06 +0000
parents e061769cc742
children 33989b5b8d02
files loader/dshow/DS_AudioDecoder.c loader/dshow/DS_AudioDecoder.h loader/dshow/DS_VideoDecoder.c loader/dshow/DS_VideoDecoder.h
diffstat 4 files changed, 592 insertions(+), 357 deletions(-) [+]
line wrap: on
line diff
--- a/loader/dshow/DS_AudioDecoder.c	Wed Nov 21 22:56:38 2001 +0000
+++ b/loader/dshow/DS_AudioDecoder.c	Wed Nov 21 23:42:06 2001 +0000
@@ -8,8 +8,7 @@
 #include "DS_AudioDecoder.h"
 #include <string.h>
 #include <stdio.h>
-
-// using namespace std;
+#include <stdlib.h>
 
 #define __MODULE__ "DirectShow audio decoder"
 const GUID FORMAT_WaveFormatEx = {
@@ -27,58 +26,71 @@
 
 typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**);
 
-DS_AudioDecoder::DS_AudioDecoder(const CodecInfo& info, const WAVEFORMATEX* wf)
-    : IAudioDecoder(info, wf), m_pDS_Filter(0), m_sVhdr(0), m_sVhdr2(0)
+DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf)
 {
-    int sz = 18 + wf->cbSize;
-    m_sVhdr=new char[sz];
-    memcpy(m_sVhdr, wf, sz);
-    m_sVhdr2=new char[sz];
-    memcpy(m_sVhdr2, m_sVhdr, sz);
-    WAVEFORMATEX* pWF=(WAVEFORMATEX*)m_sVhdr2;
-    pWF->wFormatTag=1;
-    pWF->wBitsPerSample=16;
-    pWF->nBlockAlign=2*pWF->nChannels;
-    pWF->cbSize=0;
-    in_fmt=*wf;
+    DS_AudioDecoder *this;
+    int sz;
+    WAVEFORMATEX* pWF;
+        
+    this = malloc(sizeof(DS_AudioDecoder));
+    
+    sz = 18 + wf->cbSize;
+    this->m_sVhdr = malloc(sz);
+    memcpy(this->m_sVhdr, wf, sz);
+    this->m_sVhdr2 = malloc(sz);
+    memcpy(this->m_sVhdr2, this->m_sVhdr, sz);
+    
+    pWF = (WAVEFORMATEX*)this->m_sVhdr2;
+    pWF->wFormatTag = 1;
+    pWF->wBitsPerSample = 16;
+    pWF->nBlockAlign = 2*pWF->nChannels;
+    pWF->cbSize = 0;
+    
+    memcpy(&this->in_fmt,wf,sizeof(WAVEFORMATEX));
 
-    memset(&m_sOurType, 0, sizeof(m_sOurType));
-    m_sOurType.majortype=MEDIATYPE_Audio;
-    m_sOurType.subtype=MEDIASUBTYPE_PCM;
-    m_sOurType.subtype.f1=wf->wFormatTag;
-    m_sOurType.formattype=FORMAT_WaveFormatEx;
-    m_sOurType.lSampleSize=wf->nBlockAlign;
-    m_sOurType.bFixedSizeSamples=true;
-    m_sOurType.bTemporalCompression=false;
-    m_sOurType.pUnk=0;
-    m_sOurType.cbFormat=sz;
-    m_sOurType.pbFormat=m_sVhdr;
+    memset(&this->m_sOurType, 0, sizeof(this->m_sOurType));
+    this->m_sOurType.majortype=MEDIATYPE_Audio;
+    this->m_sOurType.subtype=MEDIASUBTYPE_PCM;
+    this->m_sOurType.subtype.f1=wf->wFormatTag;
+    this->m_sOurType.formattype=FORMAT_WaveFormatEx;
+    this->m_sOurType.lSampleSize=wf->nBlockAlign;
+    this->m_sOurType.bFixedSizeSamples=1;
+    this->m_sOurType.bTemporalCompression=0;
+    this->m_sOurType.pUnk=0;
+    this->m_sOurType.cbFormat=sz;
+    this->m_sOurType.pbFormat=this->m_sVhdr;
 
-    memset(&m_sDestType, 0, sizeof(m_sDestType));
-    m_sDestType.majortype=MEDIATYPE_Audio;
-    m_sDestType.subtype=MEDIASUBTYPE_PCM;
-    m_sDestType.formattype=FORMAT_WaveFormatEx;
-    m_sDestType.bFixedSizeSamples=true;
-    m_sDestType.bTemporalCompression=false;
-    m_sDestType.lSampleSize=2*wf->nChannels;
-    m_sDestType.pUnk=0;
-    m_sDestType.cbFormat=pWF->cbSize;
-    m_sDestType.pbFormat=m_sVhdr2;
+    memset(&this->m_sDestType, 0, sizeof(this->m_sDestType));
+    this->m_sDestType.majortype=MEDIATYPE_Audio;
+    this->m_sDestType.subtype=MEDIASUBTYPE_PCM;
+    this->m_sDestType.subtype.f1=pWF->wFormatTag;
+    this->m_sDestType.formattype=FORMAT_WaveFormatEx;
+    this->m_sDestType.bFixedSizeSamples=1;
+    this->m_sDestType.bTemporalCompression=0;
+    this->m_sDestType.lSampleSize=2*wf->nChannels;
+    this->m_sDestType.pUnk=0;
+    this->m_sDestType.cbFormat=pWF->cbSize;
+    this->m_sDestType.pbFormat=this->m_sVhdr2;
 
-    try
+    /*try*/
     {
-        m_pDS_Filter = new DS_Filter();
-	m_pDS_Filter->Create(info.dll, &info.guid, &m_sOurType, &m_sDestType);
-	m_pDS_Filter->Start();
+        ALLOCATOR_PROPERTIES props, props1;
+        this->m_pDS_Filter = DS_Filter_Create((const char*)info->dll, &info->guid, &this->m_sOurType, &this->m_sDestType);
+	if( !this->m_pDS_Filter ) {
+           free(this);
+           return NULL;
+        }
+        
+        DS_Filter_Start(this->m_pDS_Filter);
 
-	ALLOCATOR_PROPERTIES props, props1;
 	props.cBuffers=1;
-        props.cbBuffer=m_sOurType.lSampleSize;
+        props.cbBuffer=this->m_sOurType.lSampleSize;
 	props.cbAlign=props.cbPrefix=0;
-	m_pDS_Filter->m_pAll->vt->SetProperties(m_pDS_Filter->m_pAll, &props, &props1);
-	m_pDS_Filter->m_pAll->vt->Commit(m_pDS_Filter->m_pAll);
+	this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1);
+	this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll);
     }
-    catch (FatalError e)
+    /*
+    catch (FatalError& e)
     {
 	e.PrintAll();
 	delete[] m_sVhdr;
@@ -86,46 +98,52 @@
 	delete m_pDS_Filter;
 	throw;
     }
+    */
+    return this;
 }
 
-DS_AudioDecoder::~DS_AudioDecoder()
+void DS_AudioDecoder_Destroy(DS_AudioDecoder *this)
 {
-    delete[] m_sVhdr;
-    delete[] m_sVhdr2;
-    delete m_pDS_Filter;
+    free(this->m_sVhdr);
+    free(this->m_sVhdr2);
+    DS_Filter_Destroy(this->m_pDS_Filter);
+    free(this);
 }
 
-int DS_AudioDecoder::Convert(const void* in_data, uint_t in_size,
-			void* out_data, uint_t out_size,
-			uint_t* size_read, uint_t* size_written)
+int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, uint_t in_size,
+			     void* out_data, uint_t out_size,
+			     uint_t* size_read, uint_t* size_written)
 {
+    uint_t written = 0;
+    uint_t read = 0;
+        
     if (!in_data || !out_data)
 	return -1;
 
-    uint_t written = 0;
-    uint_t read = 0;
-    in_size -= in_size%in_fmt.nBlockAlign;
+    in_size -= in_size%this->in_fmt.nBlockAlign;
     while (in_size>0)
     {
-	uint_t frame_size=0;
+	uint_t frame_size = 0;
 	char* frame_pointer;
-//	m_pOurOutput->SetFramePointer(out_data+written);
-	m_pDS_Filter->m_pOurOutput->SetFramePointer(&frame_pointer);
-	m_pDS_Filter->m_pOurOutput->SetFrameSizePointer((long*)&frame_size);
 	IMediaSample* sample=0;
-	m_pDS_Filter->m_pAll->vt->GetBuffer(m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
-	if(!sample)
+	char* ptr;
+	int result;
+	
+//	this->m_pOurOutput->SetFramePointer(out_data+written);
+	COutputPin_SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer);
+	COutputPin_SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size);
+	this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
+	if (!sample)
 	{
 	    Debug printf("DS_AudioDecoder::Convert() Error: null sample\n");
 	    break;
 	}
-	char* ptr;
 	sample->vt->GetPointer(sample, (BYTE **)&ptr);
-	memcpy(ptr, (const uint8_t*)in_data + read, in_fmt.nBlockAlign);
-	sample->vt->SetActualDataLength(sample, in_fmt.nBlockAlign);
-	sample->vt->SetSyncPoint(sample, true);
+	memcpy(ptr, (const uint8_t*)in_data + read, this->in_fmt.nBlockAlign);
+	sample->vt->SetActualDataLength(sample, this->in_fmt.nBlockAlign);
+	sample->vt->SetSyncPoint(sample, 1);
 	sample->vt->SetPreroll(sample, 0);
-	int result = m_pDS_Filter->m_pImp->vt->Receive(m_pDS_Filter->m_pImp, sample);
+	result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample);
         if (result)
 	    Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result);
 	if ((written + frame_size) > out_size)
@@ -135,7 +153,7 @@
 	}
 	memcpy((uint8_t*)out_data + written, frame_pointer, frame_size);
         sample->vt->Release((IUnknown*)sample);
-	read+=in_fmt.nBlockAlign;
+	read+=this->in_fmt.nBlockAlign;
 	written+=frame_size;
     }
     if (size_read)
@@ -145,12 +163,13 @@
     return 0;
 }
 
-int DS_AudioDecoder::GetSrcSize(int dest_size)
+int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size)
 {
-    double efficiency = (double) in_fmt.nAvgBytesPerSec
-	/ (in_fmt.nSamplesPerSec*in_fmt.nBlockAlign);
-    int frames = int(dest_size*efficiency);
+    double efficiency =(double) this->in_fmt.nAvgBytesPerSec
+	/ (this->in_fmt.nSamplesPerSec*this->in_fmt.nBlockAlign);
+    int frames = (int)(dest_size*efficiency);;
+    
     if (frames < 1)
 	frames = 1;
-    return frames * in_fmt.nBlockAlign;
+    return frames * this->in_fmt.nBlockAlign;
 }
--- a/loader/dshow/DS_AudioDecoder.h	Wed Nov 21 22:56:38 2001 +0000
+++ b/loader/dshow/DS_AudioDecoder.h	Wed Nov 21 23:42:06 2001 +0000
@@ -1,21 +1,36 @@
-#ifndef AVIFILE_DSHOW_H
-#define AVIFILE_DSHOW_H
+#ifndef AVIFILE_DS_AUDIODECODER_H
+#define AVIFILE_DS_AUDIODECODER_H
 
-#include "libwin32.h"
+#ifndef NOAVIFILE_HEADERS
+#include "audiodecoder.h"
+#include "except.h"
+#else
+#include "../libwin32.h"
+#endif
 #include "DS_Filter.h"
 
-class DS_AudioDecoder : public IAudioDecoder
-{
-public:
-    DS_AudioDecoder(const CodecInfo& info, const WAVEFORMATEX*);
-    virtual ~DS_AudioDecoder();
-    virtual int Convert(const void*, size_t, void*, size_t, size_t*, size_t*);
-    virtual int GetSrcSize(int);
-protected:
+typedef struct _DS_AudioDecoder
+{ 
+    WAVEFORMATEX in_fmt;
     AM_MEDIA_TYPE m_sOurType, m_sDestType;
     DS_Filter* m_pDS_Filter;
     char* m_sVhdr;
     char* m_sVhdr2;
-};
+}DS_AudioDecoder;
+
+#ifndef uint_t
+#define uint_t int
+#endif
+
+DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf);
 
-#endif
+void DS_AudioDecoder_Destroy(DS_AudioDecoder *this);
+
+int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, uint_t in_size,
+			     void* out_data, uint_t out_size,
+			     uint_t* size_read, uint_t* size_written);
+
+int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size);
+
+
+#endif // AVIFILE_DS_AUDIODECODER_H
--- a/loader/dshow/DS_VideoDecoder.c	Wed Nov 21 22:56:38 2001 +0000
+++ b/loader/dshow/DS_VideoDecoder.c	Wed Nov 21 23:42:06 2001 +0000
@@ -9,214 +9,274 @@
 #include "interfaces.h"
 
 #include "DS_VideoDecoder.h"
-#include "wine/winerror.h"
-#include "ldt_keeper.h"
-//#include <wine/winerror.h>
+#include "../wine/winerror.h"
+
+#ifndef NOAVIFILE_HEADERS
+#define VFW_E_NOT_RUNNING               0x80040226
+#include "fourcc.h"
+#include "except.h"
+#endif
 
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>  // labs
 
-//#include <cstdio>
-#include <iostream>
-//#include <strstream>
+// strcmp((const char*)info.dll,...)  is used instead of  (... == ...)
+// so Arpi could use char* pointer in his simplified DS_VideoDecoder class
 
 #define __MODULE__ "DirectShow_VideoDecoder"
 
-using namespace std;
+#define false 0
+#define true 1
+
+int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this)
+{return this->m_Caps;}
+	    
+typedef struct _ct ct;
 
-DS_VideoDecoder::DS_VideoDecoder(const CodecInfo& info, const BITMAPINFOHEADER& format, int flip)
-    :IVideoDecoder(info, format)
+struct _ct {
+		unsigned int bits;
+		fourcc_t fcc;
+		GUID *subtype;
+		int cap;
+	    };
+            
+static ct check[] = {
+		{16, fccYUY2, &MEDIASUBTYPE_YUY2, CAP_YUY2},
+		{12, fccIYUV, &MEDIASUBTYPE_IYUV, CAP_IYUV},
+		{16, fccUYVY, &MEDIASUBTYPE_UYVY, CAP_UYVY},
+		{12, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12},
+		{16, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12},
+		{16, fccYVYU, &MEDIASUBTYPE_YVYU, CAP_YVYU},
+		//{12, fccI420, &MEDIASUBTYPE_I420, CAP_I420},
+		{0},
+	    };
+
+
+DS_VideoDecoder * DS_VideoDecoder_Create(CodecInfo * info,  BITMAPINFOHEADER * format, int flip, int maxauto)
 {
-    m_sVhdr2 = 0;
-    m_iLastQuality = -1;
+    DS_VideoDecoder *this;
+    HRESULT result;
+    ct* c;
+                        
+    this = malloc(sizeof(DS_VideoDecoder));
+    memset( this, 0, sizeof(DS_VideoDecoder));
+    
+    this->m_sVhdr2 = 0;
+    this->m_iLastQuality = -1;
+    this->m_iMaxAuto = maxauto;
+
     //memset(&m_obh, 0, sizeof(m_obh));
     //m_obh.biSize = sizeof(m_obh);
-    try
+    /*try*/
     {
-	m_pDS_Filter = new DS_Filter();
-
-	unsigned bihs = (format.biSize < (int) sizeof(BITMAPINFOHEADER)) ?
-	    sizeof(BITMAPINFOHEADER) : format.biSize;
+        unsigned int bihs;
+        
+	bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ?
+	    sizeof(BITMAPINFOHEADER) : format->biSize;
         bihs = sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER) + bihs;
-
-	m_sVhdr = (VIDEOINFOHEADER*) new char[bihs];
-	memset(m_sVhdr, 0, bihs);
-	memcpy(&m_sVhdr->bmiHeader, m_bh, m_bh->biSize);
-	m_sVhdr->rcSource.left = m_sVhdr->rcSource.top = 0;
-	m_sVhdr->rcSource.right = m_sVhdr->bmiHeader.biWidth;
-        m_sVhdr->rcSource.bottom = m_sVhdr->bmiHeader.biHeight;
-	m_sVhdr->rcTarget = m_sVhdr->rcSource;
-
-	m_sOurType.majortype = MEDIATYPE_Video;
-	m_sOurType.subtype = MEDIATYPE_Video;
-        m_sOurType.subtype.f1 = m_sVhdr->bmiHeader.biCompression;
-	m_sOurType.formattype = FORMAT_VideoInfo;
-        m_sOurType.bFixedSizeSamples = false;
-	m_sOurType.bTemporalCompression = true;
-	m_sOurType.pUnk = 0;
-        m_sOurType.cbFormat = bihs;
-        m_sOurType.pbFormat = (char*)m_sVhdr;
+     
+        this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs);
+        memcpy(this->iv.m_bh, format, bihs);
+        this->iv.m_State = STOP;
+        //this->iv.m_pFrame = 0;
+        this->iv.m_Mode = DIRECT;
+        this->iv.m_iDecpos = 0;
+        this->iv.m_iPlaypos = -1;
+        this->iv.m_fQuality = 0.0f;
+        this->iv.m_bCapable16b = true;
+                
+	this->m_sVhdr = (VIDEOINFOHEADER*)malloc(bihs);
+	memset(this->m_sVhdr, 0, bihs);
+	memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize);
+	this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0;
+	this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth;
+	this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight;
+	//this->m_sVhdr->rcSource.right = 0;
+	//this->m_sVhdr->rcSource.bottom = 0;
+	this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource;
 
-	m_sVhdr2 = (VIDEOINFOHEADER*)(new char[sizeof(VIDEOINFOHEADER)+12]);
-	memcpy(m_sVhdr2, m_sVhdr, sizeof(VIDEOINFOHEADER));
-	memset((char*)m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12);
-	m_sVhdr2->bmiHeader.biCompression = 0;
-	m_sVhdr2->bmiHeader.biBitCount = 24;
+	this->m_sOurType.majortype = MEDIATYPE_Video;
+	this->m_sOurType.subtype = MEDIATYPE_Video;
+        this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression;
+	this->m_sOurType.formattype = FORMAT_VideoInfo;
+        this->m_sOurType.bFixedSizeSamples = false;
+	this->m_sOurType.bTemporalCompression = true;
+	this->m_sOurType.pUnk = 0;
+        this->m_sOurType.cbFormat = bihs;
+        this->m_sOurType.pbFormat = (char*)this->m_sVhdr;
+
+	this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12));
+	memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER));
+        memset((char*)this->m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12);
+	this->m_sVhdr2->bmiHeader.biCompression = 0;
+	this->m_sVhdr2->bmiHeader.biBitCount = 24;
 
-	memset(&m_sDestType, 0, sizeof(m_sDestType));
-	m_sDestType.majortype = MEDIATYPE_Video;
-	m_sDestType.subtype = MEDIASUBTYPE_RGB24;
-	m_sDestType.formattype = FORMAT_VideoInfo;
-	m_sDestType.bFixedSizeSamples = true;
-	m_sDestType.bTemporalCompression = false;
-	m_sDestType.lSampleSize = abs(m_sVhdr2->bmiHeader.biWidth*m_sVhdr2->bmiHeader.biHeight
-				      * ((m_sVhdr2->bmiHeader.biBitCount + 7) / 8));
-	m_sVhdr2->bmiHeader.biSizeImage = m_sDestType.lSampleSize;
-	m_sDestType.pUnk = 0;
-	m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
-        m_sDestType.pbFormat = (char*)m_sVhdr2;
-	memset(&m_obh, 0, sizeof(m_obh));
-	memcpy(&m_obh, m_bh, sizeof(m_obh) < m_bh->biSize ? sizeof(m_obh) : m_bh->biSize);
-	m_obh.SetBits(24);
+	memset(&this->m_sDestType, 0, sizeof(this->m_sDestType));
+	this->m_sDestType.majortype = MEDIATYPE_Video;
+	this->m_sDestType.subtype = MEDIASUBTYPE_RGB24;
+	this->m_sDestType.formattype = FORMAT_VideoInfo;
+	this->m_sDestType.bFixedSizeSamples = true;
+	this->m_sDestType.bTemporalCompression = false;
+	this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight
+				       * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8));
+	this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize;
+	this->m_sDestType.pUnk = 0;
+	this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
+	this->m_sDestType.pbFormat = (char*)this->m_sVhdr2;
+        
+        memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh));
+	memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize
+	       ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize);
+	this->iv.m_obh.biBitCount=24;
+        this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER);
+        this->iv.m_obh.biCompression = 0;	//BI_RGB
+        //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight);
+        this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight)
+                              * ((this->iv.m_obh.biBitCount + 7) / 8);
 
-	HRESULT result;
 
-	m_pDS_Filter->Create(info.dll, &info.guid, &m_sOurType, &m_sDestType);
+	this->m_pDS_Filter = DS_Filter_Create((const char*)info->dll, &info->guid, &this->m_sOurType, &this->m_sDestType);
 
 	if (!flip)
 	{
-	    m_sVhdr2->bmiHeader.biHeight *= -1;
-	    m_obh.biHeight *= -1;
-	    result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType);
+	    this->m_sVhdr2->bmiHeader.biHeight *= -1;
+	    this->iv.m_obh.biHeight *= -1;
+	    result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType);
 	    if (result)
 	    {
-		cerr << "Decoder does not support upside-down frames" << endl;
-		m_sVhdr2->bmiHeader.biHeight *= -1;
-		m_obh.biHeight *= -1;
+		printf("Decoder does not support upside-down frames\n");
+		this->m_sVhdr2->bmiHeader.biHeight *= -1;
+		this->iv.m_obh.biHeight *= -1;
 	    }
 	}
 
-	m_decoder = m_obh;
+        memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) );
 
-	switch (m_bh->biCompression)
+	switch (this->iv.m_bh->biCompression)
 	{
 	case fccDIV3:
 	case fccDIV4:
 	case fccDIV5:
+	case fccDIV6:
 	case fccMP42:
 	case fccWMV2:
 	    //YV12 seems to be broken for DivX :-) codec
-//	case fccIV50:
+	case fccIV50:
 	    //produces incorrect picture
 	    //m_Caps = (CAPS) (m_Caps & ~CAP_YV12);
-	    m_Caps = CAP_YUY2; // | CAP_I420;
+	    //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420;
+	    //m_Caps = CAP_I420;
+	    this->m_Caps = (CAP_YUY2 | CAP_UYVY);
 	    break;
 	default:
-	    struct ct {
-		unsigned int bits;
-		fourcc_t fcc;
-		GUID subtype;
-		CAPS cap;
-	    } check[] = {
-		{16, fccYUY2, MEDIASUBTYPE_YUY2, CAP_YUY2},
-		{12, fccIYUV, MEDIASUBTYPE_IYUV, CAP_IYUV},
-		{16, fccUYVY, MEDIASUBTYPE_UYVY, CAP_UYVY},
-		{12, fccYV12, MEDIASUBTYPE_YV12, CAP_YV12},
-		{16, fccYV12, MEDIASUBTYPE_YV12, CAP_YV12},
-		{16, fccYVYU, MEDIASUBTYPE_YVYU, CAP_YVYU},
-		//{12, fccI420, MEDIASUBTYPE_I420, CAP_I420},
-		{0},
-	    };
+              
+	    this->m_Caps = CAP_NONE;
 
-	    m_Caps = CAP_NONE;
-
-	    for (ct* c = check; c->bits; c++)
+	    for (c = check; c->bits; c++)
 	    {
-		m_sVhdr2->bmiHeader.biBitCount = c->bits;
-		m_sVhdr2->bmiHeader.biCompression = c->fcc;
-		m_sDestType.subtype = c->subtype;
-		result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType);
+		this->m_sVhdr2->bmiHeader.biBitCount = c->bits;
+		this->m_sVhdr2->bmiHeader.biCompression = c->fcc;
+		this->m_sDestType.subtype = *c->subtype;
+		result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType);
 		if (!result)
-		    m_Caps = (CAPS)(m_Caps | c->cap);
+		    this->m_Caps = (this->m_Caps | c->cap);
 	    }
 	}
 
-	if (m_Caps != CAP_NONE)
-	    cout << "Decoder is capable of YUV output ( flags 0x"<<hex<<(int)m_Caps<<dec<<" )"<<endl;
+	if (this->m_Caps != CAP_NONE)
+	    printf("Decoder is capable of YUV output ( flags 0x%x)\n", (int)this->m_Caps);
 
-	m_sVhdr2->bmiHeader.biBitCount = 24;
-	m_sVhdr2->bmiHeader.biCompression = 0;
-	m_sDestType.subtype = MEDIASUBTYPE_RGB24;
+	this->m_sVhdr2->bmiHeader.biBitCount = 24;
+	this->m_sVhdr2->bmiHeader.biCompression = 0;
+	this->m_sDestType.subtype = MEDIASUBTYPE_RGB24;
 
-	m_bIsDivX = ((strcmp(info.dll,"divxcvki.ax")==0)
-		  || (strcmp(info.dll,"divx_c32.ax")==0)
-		  || (strcmp(info.dll,"wmvds32.ax")==0)
-		  || (strcmp(info.dll,"wmv8ds32.ax")==0) );
-
-	printf("m_bIsDivX=%d\n",m_bIsDivX);
+	this->m_iMinBuffers = this->iv.VBUFSIZE;
+	this->m_bIsDivX = (strcmp((const char*)info->dll, "divxcvki.ax") == 0
+		     || strcmp((const char*)info->dll, "divx_c32.ax") == 0
+		     || strcmp((const char*)info->dll, "wmvds32.ax") == 0
+		     || strcmp((const char*)info->dll, "wmv8ds32.ax") == 0);
+	this->m_bIsDivX4 = (strcmp((const char*)info->dll, "divxdec.ax") == 0);
+	if (this->m_bIsDivX)
+	    this->iv.VBUFSIZE += 7;
+	else if (this->m_bIsDivX4)
+	    this->iv.VBUFSIZE += 9;
     }
-    catch (FatalError& error)
+    /*catch (FatalError& error)
     {
+        delete[] m_sVhdr;
 	delete[] m_sVhdr2;
         delete m_pDS_Filter;
 	throw;
-    }
+    }*/
+    return this;
 }
 
-DS_VideoDecoder::~DS_VideoDecoder()
+void DS_VideoDecoder_Destroy(DS_VideoDecoder *this)
 {
-    Stop();
-    delete[] m_sVhdr2;
-    delete m_pDS_Filter;
+    DS_VideoDecoder_StopInternal(this);
+    this->iv.m_State = STOP;
+    free(this->m_sVhdr);
+    free(this->m_sVhdr2);
+    DS_Filter_Destroy(this->m_pDS_Filter);
 }
 
-void DS_VideoDecoder::StartInternal()
+void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this)
 {
+    ALLOCATOR_PROPERTIES props, props1;
+    Debug printf("DS_VideoDecoder_StartInternal\n");
     //cout << "DSSTART" << endl;
-    m_pDS_Filter->Start();
-    ALLOCATOR_PROPERTIES props, props1;
+    DS_Filter_Start(this->m_pDS_Filter);
+    
     props.cBuffers = 1;
-    props.cbBuffer = m_sDestType.lSampleSize;
+    props.cbBuffer = this->m_sDestType.lSampleSize;
+
     //don't know how to do this correctly
     props.cbAlign = props.cbPrefix = 0;
-    m_pDS_Filter->m_pAll->vt->SetProperties(m_pDS_Filter->m_pAll, &props, &props1);
-    m_pDS_Filter->m_pAll->vt->Commit(m_pDS_Filter->m_pAll);
+    this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1);
+    this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll);
+    
+    //this->iv.m_State = START;
 }
 
-void DS_VideoDecoder::StopInternal()
+void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this)
 {
-    //cout << "DSSTOP" << endl;
-    m_pDS_Filter->Stop();
+    DS_Filter_Stop(this->m_pDS_Filter);
     //??? why was this here ??? m_pOurOutput->SetFramePointer(0);
 }
 
-int DS_VideoDecoder::DecodeInternal(void* src, size_t size, int is_keyframe, CImage* pImage)
+int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, CImage* pImage)
 {
     IMediaSample* sample = 0;
-
-    m_pDS_Filter->m_pAll->vt->GetBuffer(m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
-
+    char* ptr;
+    int result;
+    
+    Debug printf("DS_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,pImage->ptr);
+            
+    this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
+    
     if (!sample)
     {
-	Debug cerr << "ERROR: null sample" << endl;
+	Debug printf("ERROR: null sample\n");
 	return -1;
     }
-
+    
     //cout << "DECODE " << (void*) pImage << "   d: " << (void*) pImage->Data() << endl;
     if (pImage)
     {
-	if (!(pImage->Data()))
+	if (!(pImage->ptr))
 	{
-	    Debug cout << "no m_outFrame??" << endl;
+	    Debug printf("no m_outFrame??\n");
 	}
 	else
-	    m_pDS_Filter->m_pOurOutput->SetPointer2((char*)pImage->Data());
+	    COutputPin_SetPointer2(this->m_pDS_Filter->m_pOurOutput,(char*)pImage->ptr);
     }
 
-    char* ptr;
+
     sample->vt->GetPointer(sample, (BYTE **)&ptr);
     memcpy(ptr, src, size);
     sample->vt->SetActualDataLength(sample, size);
@@ -230,14 +290,14 @@
     // crashes inside ...->Receive() fixed now?
     //
     // nope - but this is surely helpfull - I'll try some more experiments
-    Setup_FS_Segment();
+    //Setup_FS_Segment();
 #if 0
-    if (!m_pDS_Filter || !m_pDS_Filter->m_pImp
-	|| !m_pDS_Filter->m_pImp->vt
-	|| !m_pDS_Filter->m_pImp->vt->Receive)
+    if (!this->m_pDS_Filter || !this->m_pDS_Filter->m_pImp
+	|| !this->m_pDS_Filter->m_pImp->vt
+	|| !this->m_pDS_Filter->m_pImp->vt->Receive)
 	printf("DecodeInternal ERROR???\n");
 #endif
-    int result = m_pDS_Filter->m_pImp->vt->Receive(m_pDS_Filter->m_pImp, sample);
+    result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample);
     if (result)
     {
 	Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result);
@@ -245,62 +305,70 @@
 
     sample->vt->Release((IUnknown*)sample);
 
-    if (m_bIsDivX)
+#if 0
+    if (this->m_bIsDivX)
     {
 	int q;
-	IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8);
+	IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8);
 	// always check for actual value
 	// this seems to be the only way to know the actual value
-	hidden->vt->GetSmth2(hidden, &m_iLastQuality);
-	if (m_iLastQuality > 9)
-	    m_iLastQuality -= 10;
+	hidden->vt->GetSmth2(hidden, &this->m_iLastQuality);
+	if (this->m_iLastQuality > 9)
+	    this->m_iLastQuality -= 10;
+
+	if (this->m_iLastQuality < 0)
+	    this->m_iLastQuality = 0;
+	else if (this->m_iLastQuality > this->m_iMaxAuto)
+	    this->m_iLastQuality = this->m_iMaxAuto;
 
-	if (m_iLastQuality < 0)
-	    m_iLastQuality = 0;
-	else if (m_iLastQuality > 4)
-	    m_iLastQuality = 4;
+	//cout << " Qual: " << this->m_iLastQuality << endl;
+	this->iv.m_fQuality = this->m_iLastQuality / 4.0;
+    }
+    else if (this->m_bIsDivX4)
+    {
+
+        // maybe access methods directly to safe some cpu cycles...
+        DS_VideoDecoder_GetValue(this, "Postprocessing", this->m_iLastQuality);
+	if (this->m_iLastQuality < 0)
+	    this->m_iLastQuality = 0;
+	else if (this->m_iLastQuality > this->m_iMaxAuto)
+	    this->m_iLastQuality = this->m_iMaxAuto;
 
 	//cout << " Qual: " << m_iLastQuality << endl;
-	m_fQuality = m_iLastQuality / 4.0;
+	this->iv.m_fQuality = this->m_iLastQuality / 6.0;
     }
 
-    // FIXME: last_quality currently works only for DivX movies
-    // more general approach is needed here
-    // cout << "Q: " << m_iLastQuality << "  rt: " << m_Mode << " dp: " << decpos << endl;
-    // also accesing vbuf doesn't look very nice at this place
-    // FIXME later - do it as a virtual method
-
-    if (m_Mode == IVideoDecoder::REALTIME_QUALITY_AUTO)
+    if (this->iv.m_Mode == -1 ) // ???BUFFERED_QUALITY_AUTO)
     {
 	// adjust Quality - depends on how many cached frames we have
-	int buffered = m_iDecpos - m_iPlaypos;
-
-	if (m_bIsDivX)
-	{
-	    //cout << "qual " << q << "  " << buffered << endl;
-	    if (buffered < (m_iLastQuality * 2 + QMARKLO - 1)
-		|| buffered > ((m_iLastQuality + 1) * 2 + QMARKLO))
-	    {
-		// removed old code which was present here
-		// and replaced with this new uptodate one
+	int buffered = this->iv.m_iDecpos - this->iv.m_iPlaypos;
 
-		int to = (buffered - QMARKLO) / 2;
-		if (to < 0)
-		    to = 0;
-		else if (to > 4)
-		    to = 4;
-		if (m_iLastQuality != to)
+	if (this->m_bIsDivX || this->m_bIsDivX4)
+	{
+	    int to = buffered - this->m_iMinBuffers;
+	    if (to < 0)
+		to = 0;
+	    if (to != this->m_iLastQuality)
+	    {
+		if (to > this->m_iMaxAuto)
+		    to = this->m_iMaxAuto;
+		if (this->m_iLastQuality != to)
 		{
-		    IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8);
-		    hidden->vt->SetSmth(hidden, to, 0);
+		    if (this->m_bIsDivX)
+		    {
+			IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8);
+			hidden->vt->SetSmth(hidden, to, 0);
+		    }
+                    else
+			DS_VideoDecoder_SetValue(this, "Postprocessing", to);
 #ifndef QUIET
-		    //cout << "Switching quality " << m_iLastQuality <<  " -> " << to << "  b:" << buffered << endl;
+		    //printf("Switching quality %d -> %d  b:%d\n",m_iLastQuality, to, buffered);
 #endif
 		}
 	    }
 	}
     }
-
+#endif
 
     return 0;
 }
@@ -308,168 +376,254 @@
 /*
  * bits == 0   - leave unchanged
  */
-int DS_VideoDecoder::SetDestFmt(int bits, fourcc_t csp)
+//int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0);
+int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, fourcc_t csp)
 {
-    if (!CImage::Supported(csp, bits))
+    HRESULT result;
+    int should_test=1;
+    int stoped = 0;   
+    
+    Debug printf("DS_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp);
+        
+       /* if (!CImage::Supported(csp, bits))
 	return -1;
-
+*/
     // BitmapInfo temp = m_obh;
+    
     if (bits != 0)
     {
-	bool ok = true;
+	int ok = true;
 
 	switch (bits)
         {
 	case 15:
-	    m_sDestType.subtype = MEDIASUBTYPE_RGB555;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB555;
     	    break;
 	case 16:
-	    m_sDestType.subtype = MEDIASUBTYPE_RGB565;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB565;
 	    break;
 	case 24:
-	    m_sDestType.subtype = MEDIASUBTYPE_RGB24;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB24;
 	    break;
 	case 32:
-	    m_sDestType.subtype = MEDIASUBTYPE_RGB32;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB32;
 	    break;
 	default:
             ok = false;
 	    break;
 	}
 
-        if (ok)
-	    m_obh.SetBits(bits);
+        if (ok) {
+	    this->iv.m_obh.biBitCount=bits;
+            if( bits == 15 || bits == 16 ) {
+	      this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12;
+	      this->iv.m_obh.biCompression=3;//BI_BITFIELDS
+	      this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight));
+	    }
+            
+            if( bits == 16 ) {
+	      this->iv.m_obh.colors[0]=0xF800;
+	      this->iv.m_obh.colors[1]=0x07E0;
+	      this->iv.m_obh.colors[2]=0x001F;
+            } else if ( bits == 15 ) {
+	      this->iv.m_obh.colors[0]=0x7C00;
+	      this->iv.m_obh.colors[1]=0x03E0;
+	      this->iv.m_obh.colors[2]=0x001F;
+            } else {
+	      this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER);
+	      this->iv.m_obh.biCompression = 0;	//BI_RGB
+	      //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight);
+	      this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight)
+                              * ((this->iv.m_obh.biBitCount + 7) / 8);
+            }
+        }
 	//.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8));
     }
 
     if (csp != 0)
     {
-        bool ok = true;
+        int ok = true;
 	switch (csp)
 	{
 	case fccYUY2:
-	    m_sDestType.subtype = MEDIASUBTYPE_YUY2;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_YUY2;
 	    break;
 	case fccYV12:
-	    m_sDestType.subtype = MEDIASUBTYPE_YV12;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_YV12;
 	    break;
 	case fccIYUV:
-	    m_sDestType.subtype = MEDIASUBTYPE_IYUV;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_IYUV;
 	    break;
 	case fccUYVY:
-	    m_sDestType.subtype = MEDIASUBTYPE_UYVY;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_UYVY;
 	    break;
 	case fccYVYU:
-	    m_sDestType.subtype = MEDIASUBTYPE_YVYU;
+	    this->m_sDestType.subtype = MEDIASUBTYPE_YVYU;
 	    break;
 	default:
 	    ok = false;
             break;
 	}
 
-        if (ok)
-	    m_obh.SetSpace(csp);
+        if (ok) {
+          int bits=0;
+	  switch(csp){
+	  case fccYUV:
+	    bits=24;break;
+	  case fccYUY2:
+	  case fccUYVY:
+	  case fccYVYU:
+	    bits=16;break;
+	  case fccYV12:
+	  case fccIYUV:
+	  case fccI420:
+	    bits=12;break;
+	  }
+	  if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0)
+    	    this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0
+	  this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER);
+	  this->iv.m_obh.biCompression=csp;
+	  this->iv.m_obh.biBitCount=bits;
+	  this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount*
+             this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3;
+        }
     }
-    m_sDestType.lSampleSize = m_obh.biSizeImage;
-    memcpy(&(m_sVhdr2->bmiHeader), &m_obh, sizeof(m_obh));
-    m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    if (m_sVhdr2->bmiHeader.biCompression == 3)
-        m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12;
+    this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage;
+    memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh));
+    this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    if (this->m_sVhdr2->bmiHeader.biCompression == 3)
+        this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12;
     else
-        m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
+        this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
 
-    HRESULT result;
-    bool should_test=true;
+
     switch(csp)
     {
     case fccYUY2:
-	if(!(m_Caps & CAP_YUY2))
+	if(!(this->m_Caps & CAP_YUY2))
 	    should_test=false;
 	break;
     case fccYV12:
-	if(!(m_Caps & CAP_YV12))
+	if(!(this->m_Caps & CAP_YV12))
 	    should_test=false;
 	break;
     case fccIYUV:
-	if(!(m_Caps & CAP_IYUV))
+	if(!(this->m_Caps & CAP_IYUV))
 	    should_test=false;
 	break;
     case fccUYVY:
-	if(!(m_Caps & CAP_UYVY))
+	if(!(this->m_Caps & CAP_UYVY))
 	    should_test=false;
 	break;
     case fccYVYU:
-	if(!(m_Caps & CAP_YVYU))
+	if(!(this->m_Caps & CAP_YVYU))
 	    should_test=false;
 	break;
     }
     if(should_test)
-	result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType);
+	result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType);
     else
 	result = -1;
 
     if (result != 0)
     {
 	if (csp)
-	    cerr << "Warning: unsupported color space" << endl;
+	    printf("Warning: unsupported color space\n");
 	else
-	    cerr << "Warning: unsupported bit depth" << endl;
+	    printf("Warning: unsupported bit depth\n");
 
-	m_sDestType.lSampleSize = m_decoder.biSizeImage;
-	memcpy(&(m_sVhdr2->bmiHeader), &m_decoder, sizeof(m_decoder));
-	m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-	if(m_sVhdr2->bmiHeader.biCompression == 3)
-    	    m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12;
+	this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage;
+	memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder));
+	this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+	if (this->m_sVhdr2->bmiHeader.biCompression == 3)
+    	    this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12;
 	else
-    	    m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
+    	    this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER);
 
-	return 1;
+	return -1;
     }
 
-    m_decoder = m_obh;
+    memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh));
 
 //    m_obh=temp;
 //    if(csp)
 //	m_obh.biBitCount=BitmapInfo::BitCount(csp);
-    m_bh->biBitCount = bits;
+    this->iv.m_bh->biBitCount = bits;
+
+    //DS_VideoDecoder_Restart(this);
 
-    //Restart();
-    bool stoped = false;
-    if (m_State == START)
+    if (this->iv.m_State == START)
     {
-	Stop();
+	DS_VideoDecoder_StopInternal(this);
+        this->iv.m_State = STOP;
         stoped = true;
     }
 
-    m_pDS_Filter->m_pInputPin->vt->Disconnect(m_pDS_Filter->m_pInputPin);
-    m_pDS_Filter->m_pOutputPin->vt->Disconnect(m_pDS_Filter->m_pOutputPin);
-    m_pDS_Filter->m_pOurOutput->SetNewFormat(m_sDestType);
-    result = m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(m_pDS_Filter->m_pInputPin,
-							      m_pDS_Filter->m_pOurInput,
-							      &m_sOurType);
+    this->m_pDS_Filter->m_pInputPin->vt->Disconnect(this->m_pDS_Filter->m_pInputPin);
+    this->m_pDS_Filter->m_pOutputPin->vt->Disconnect(this->m_pDS_Filter->m_pOutputPin);
+    COutputPin_SetNewFormat(this->m_pDS_Filter->m_pOurOutput,&this->m_sDestType);
+    result = this->m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pInputPin,
+							      this->m_pDS_Filter->m_pOurInput,
+							      &this->m_sOurType);
     if (result)
     {
-	cerr<<"Error reconnecting input pin "<<hex<<result<<dec<<endl;
+	printf("Error reconnecting input pin 0x%x\n", (int)result);
 	return -1;
     }
-    result = m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(m_pDS_Filter->m_pOutputPin,
-							       m_pDS_Filter->m_pOurOutput,
-							       &m_sDestType);
+    result = this->m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pOutputPin,
+							       (IPin *)this->m_pDS_Filter->m_pOurOutput,
+							       &this->m_sDestType);
     if (result)
     {
-	cerr<<"Error reconnecting output pin "<<hex<<result<<dec<<endl;
+	printf("Error reconnecting output pin 0x%x\n", (int)result);
 	return -1;
     }
 
     if (stoped)
-	Start();
+    {
+	DS_VideoDecoder_StartInternal(this);
+        this->iv.m_State = START; 
+    }
 
     return 0;
 }
 
-HRESULT DS_VideoDecoder::GetValue(const char* name, int& value)
+
+int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d)
+{
+    this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight;
+    this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight;
+    return 0;
+}
+
+HRESULT DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value)
 {
-    if (m_bIsDivX)
+/*
+    if (m_bIsDivX4)
+    {
+	IDivxFilterInterface* pIDivx;
+	if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx))
+	{
+	    Debug printf("No such interface\n");
+	    return -1;
+	}
+	if (strcmp(name, "Postprocessing") == 0)
+	{
+	    pIDivx->vt->get_PPLevel(pIDivx, &value);
+	    value /= 10;
+	}
+	else if (strcmp(name, "Brightness") == 0)
+	    pIDivx->vt->get_Brightness(pIDivx, &value);
+	else if (strcmp(name, "Contrast") == 0)
+	    pIDivx->vt->get_Contrast(pIDivx, &value);
+	else if (strcmp(name, "Saturation") == 0)
+	    pIDivx->vt->get_Saturation(pIDivx, &value);
+	else if (strcmp(name, "MaxAuto") == 0)
+	    value = m_iMaxAuto;
+	pIDivx->vt->Release((IUnknown*)pIDivx);
+	return 0;
+    }
+    else if (m_bIsDivX)
     {
 	if (m_State != START)
 	    return VFW_E_NOT_RUNNING;
@@ -485,6 +639,14 @@
 // get5=set4 19
 // get6=set5 23
 	IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter+0xb8);
+	if (strcmp(name, "Quality") == 0)
+	{
+#warning NOT SURE
+	    int r = hidden->vt->GetSmth2(hidden, &value);
+	    if (value >= 10)
+		value -= 10;
+	    return 0;
+	}
 	if (strcmp(name, "Brightness") == 0)
 	    return hidden->vt->GetSmth3(hidden, &value);
 	if (strcmp(name, "Contrast") == 0)
@@ -493,21 +655,18 @@
 	    return hidden->vt->GetSmth6(hidden, &value);
 	if (strcmp(name, "Saturation") == 0)
 	    return hidden->vt->GetSmth5(hidden, &value);
-	if (strcmp(name, "Quality") == 0)
+	if (strcmp(name, "MaxAuto") == 0)
 	{
-#warning NOT SURE
-	    int r = hidden->vt->GetSmth2(hidden, &value);
-	    if (value >= 10)
-		value -= 10;
-	    return 0;
+	    value = m_iMaxAuto;
+            return 0;
 	}
     }
-    else if (strcmp(record.dll,"ir50_32.dll")==0)
+    else if (strcmp((const char*)record.dll, "ir50_32.dll") == 0)
     {
 	IHidden2* hidden = 0;
 	if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden))
 	{
-	    cerr << "No such interface" << endl;
+	    Debug printf("No such interface\n");
 	    return -1;
 	}
 #warning FIXME
@@ -542,22 +701,40 @@
 
 	hidden->vt->Release((IUnknown*)hidden);
     }
-
+*/
     return 0;
 }
 
-HRESULT DS_VideoDecoder::SetValue(const char* name, int value)
+HRESULT DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value)
 {
-    if (m_bIsDivX)
+/*
+    if (m_bIsDivX4)
     {
-
+	IDivxFilterInterface* pIDivx;
+	if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx))
+	{
+	    Debug printf("No such interface\n");
+	    return -1;
+	}
+	if (strcmp(name, "Postprocessing") == 0)
+	    pIDivx->vt->put_PPLevel(pIDivx, value * 10);
+	else if (strcmp(name, "Brightness") == 0)
+	    pIDivx->vt->put_Brightness(pIDivx, value);
+	else if (strcmp(name, "Contrast") == 0)
+	    pIDivx->vt->put_Contrast(pIDivx, value);
+	else if (strcmp(name, "Saturation") == 0)
+	    pIDivx->vt->put_Saturation(pIDivx, value);
+	else if (strcmp(name, "MaxAuto") == 0)
+            m_iMaxAuto = value;
+	pIDivx->vt->Release((IUnknown*)pIDivx);
+	//printf("Set %s  %d\n", name, value);
+	return 0;
+    }
+    else if (m_bIsDivX)
+    {
 	if (m_State != START)
 	    return VFW_E_NOT_RUNNING;
 
-    	/* This printf is annoying with autoquality, *
-     	 * should be moved into players code - atmos */
-	//printf("DS_VideoDecoder::SetValue(%s,%d)\n",name,value);
-
 	//cout << "set value " << name << "  " << value << endl;
 // brightness 87
 // contrast 74
@@ -569,7 +746,7 @@
 // get3=set2 86
 // get4=set3 73
 // get5=set4 19
-// get6=set5 23
+	// get6=set5 23
     	IHidden* hidden = (IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8);
 	if (strcmp(name, "Quality") == 0)
 	{
@@ -584,13 +761,18 @@
 	    return hidden->vt->SetSmth4(hidden, value, 0);
 	if (strcmp(name, "Hue") == 0)
 	    return hidden->vt->SetSmth5(hidden, value, 0);
+	if (strcmp(name, "MaxAuto") == 0)
+	{
+            m_iMaxAuto = value;
+	    return 0;
+	}
     }
-    else if (strcmp(record.dll,"ir50_32.dll")==0)
+    else if (strcmp((const char*)record.dll, "ir50_32.dll") == 0)
     {
 	IHidden2* hidden = 0;
 	if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden))
 	{
-	    Debug cerr << "No such interface" << endl;
+	    Debug printf("No such interface\n");
 	    return -1;
 	}
 	int recordpar[30];
@@ -625,6 +807,7 @@
 
 	return result;
     }
+*/
     return 0;
 }
 /*
--- a/loader/dshow/DS_VideoDecoder.h	Wed Nov 21 22:56:38 2001 +0000
+++ b/loader/dshow/DS_VideoDecoder.h	Wed Nov 21 23:42:06 2001 +0000
@@ -1,37 +1,55 @@
 #ifndef AVIFILE_DS_VIDEODECODER_H
 #define AVIFILE_DS_VIDEODECODER_H
 
-#include <libwin32.h>
-#include <DS_Filter.h>
+#ifndef NOAVIFILE_HEADERS
+#include "videodecoder.h"
+#else
+#include "../libwin32.h"
+#endif
+#include "DS_Filter.h"
 
-class DS_VideoDecoder: public IVideoDecoder, public IRtConfig
+typedef struct _DS_VideoDecoder
 {
-public:
-    DS_VideoDecoder(const CodecInfo& info, const BITMAPINFOHEADER& format, int flip);
-    ~DS_VideoDecoder();
-    int SetDestFmt(int bits = 24, fourcc_t csp = 0);
-    CAPS GetCapabilities() const {return m_Caps;}
-    int DecodeInternal(void* src, size_t size, int is_keyframe, CImage* pImage);
-    void StartInternal();
-    void StopInternal();
-    //void Restart();
-    int SetDirection(int d)
-    {
-	m_obh.biHeight = d ? m_bh->biHeight : -m_bh->biHeight;
-	m_sVhdr2->bmiHeader.biHeight = m_obh.biHeight;
-	return 0;
-    }
-    // IRtConfig interface
-    virtual HRESULT GetValue(const char*, int&);
-    virtual HRESULT SetValue(const char*, int);
-protected:
+    IVideoDecoder iv;
+    
     DS_Filter* m_pDS_Filter;
     AM_MEDIA_TYPE m_sOurType, m_sDestType;
     VIDEOINFOHEADER* m_sVhdr;
     VIDEOINFOHEADER* m_sVhdr2;
-    CAPS m_Caps;                // capabilities of DirectShow decoder
+    int m_Caps;//CAPS m_Caps;                // capabilities of DirectShow decoder
     int m_iLastQuality;         // remember last quality as integer
-    bool m_bIsDivX;             // for speed
-};
+    int m_iMinBuffers;
+    int m_iMaxAuto;
+    int m_bIsDivX;             // for speed
+    int m_bIsDivX4;            // for speed
+}DS_VideoDecoder;
+
+
+
+int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this);
+
+DS_VideoDecoder * DS_VideoDecoder_Create(CodecInfo * info,  BITMAPINFOHEADER * format, int flip, int maxauto);
+
+void DS_VideoDecoder_Destroy(DS_VideoDecoder *this);
+
+void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this);
+
+void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this);
+
+int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, CImage* pImage);
+
+/*
+ * bits == 0   - leave unchanged
+ */
+//int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0);
+int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, fourcc_t csp);
+
+
+int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d);
+
+HRESULT DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value);
+
+HRESULT DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value);
+
 
 #endif /* AVIFILE_DS_VIDEODECODER_H */