diff options
author | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-21 23:42:06 +0000 |
---|---|---|
committer | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-21 23:42:06 +0000 |
commit | 937a031d525545f8cc39d2f968343450dd731c23 (patch) | |
tree | 4387ef37cd5d1f7c68901d1024c3f2c293c76282 | |
parent | bcdb01b14369a8554ab9f01e011ff0ce81d8a91f (diff) | |
download | mpv-937a031d525545f8cc39d2f968343450dd731c23.tar.bz2 mpv-937a031d525545f8cc39d2f968343450dd731c23.tar.xz |
imported from xine
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3060 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | loader/dshow/DS_AudioDecoder.c | 163 | ||||
-rw-r--r-- | loader/dshow/DS_AudioDecoder.h | 39 | ||||
-rw-r--r-- | loader/dshow/DS_VideoDecoder.c | 685 | ||||
-rw-r--r-- | loader/dshow/DS_VideoDecoder.h | 68 |
4 files changed, 595 insertions, 360 deletions
diff --git a/loader/dshow/DS_AudioDecoder.c b/loader/dshow/DS_AudioDecoder.c index 87e919c7c0..41944dd099 100644 --- a/loader/dshow/DS_AudioDecoder.c +++ b/loader/dshow/DS_AudioDecoder.c @@ -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 @@ const GUID MEDIASUBTYPE_PCM = { 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 @@ DS_AudioDecoder::DS_AudioDecoder(const CodecInfo& info, const WAVEFORMATEX* wf) 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 @@ int DS_AudioDecoder::Convert(const void* in_data, uint_t in_size, } 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 @@ int DS_AudioDecoder::Convert(const void* in_data, uint_t in_size, 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; } diff --git a/loader/dshow/DS_AudioDecoder.h b/loader/dshow/DS_AudioDecoder.h index e527156e4e..b0d01c4c83 100644 --- a/loader/dshow/DS_AudioDecoder.h +++ b/loader/dshow/DS_AudioDecoder.h @@ -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); + +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 diff --git a/loader/dshow/DS_VideoDecoder.c b/loader/dshow/DS_VideoDecoder.c index 438b2791f2..91db9fc63d 100644 --- a/loader/dshow/DS_VideoDecoder.c +++ b/loader/dshow/DS_VideoDecoder.c @@ -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; + +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(const CodecInfo& info, const BITMAPINFOHEADER& format, int flip) - :IVideoDecoder(info, format) +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; - - 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; - - 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); - - HRESULT result; - - m_pDS_Filter->Create(info.dll, &info.guid, &m_sOurType, &m_sDestType); + + 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; + + 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(&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); + + + 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; - - m_sVhdr2->bmiHeader.biBitCount = 24; - m_sVhdr2->bmiHeader.biCompression = 0; - 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); + if (this->m_Caps != CAP_NONE) + printf("Decoder is capable of YUV output ( flags 0x%x)\n", (int)this->m_Caps); + + this->m_sVhdr2->bmiHeader.biBitCount = 24; + this->m_sVhdr2->bmiHeader.biCompression = 0; + this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; + + 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) { - //cout << "DSSTART" << endl; - m_pDS_Filter->Start(); ALLOCATOR_PROPERTIES props, props1; + Debug printf("DS_VideoDecoder_StartInternal\n"); + //cout << "DSSTART" << endl; + 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 @@ int DS_VideoDecoder::DecodeInternal(void* src, size_t size, int is_keyframe, CIm // 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 @@ int DS_VideoDecoder::DecodeInternal(void* src, size_t size, int is_keyframe, CIm 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 (m_iLastQuality < 0) - m_iLastQuality = 0; - else if (m_iLastQuality > 4) - m_iLastQuality = 4; + 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; + //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; - // 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 + //cout << " Qual: " << m_iLastQuality << endl; + this->iv.m_fQuality = this->m_iLastQuality / 6.0; + } - 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; + int buffered = this->iv.m_iDecpos - this->iv.m_iPlaypos; - if (m_bIsDivX) + if (this->m_bIsDivX || this->m_bIsDivX4) { - //cout << "qual " << q << " " << buffered << endl; - if (buffered < (m_iLastQuality * 2 + QMARKLO - 1) - || buffered > ((m_iLastQuality + 1) * 2 + QMARKLO)) + int to = buffered - this->m_iMinBuffers; + if (to < 0) + to = 0; + if (to != this->m_iLastQuality) { - // removed old code which was present here - // and replaced with this new uptodate one - - int to = (buffered - QMARKLO) / 2; - if (to < 0) - to = 0; - else if (to > 4) - to = 4; - if (m_iLastQuality != to) + 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 @@ int DS_VideoDecoder::DecodeInternal(void* src, size_t size, int is_keyframe, CIm /* * 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.biCompre |