Commit f096fa3a authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

Added Video Renderer (based on Direct Draw).

Added Direct Sound Audio Renderer. Added AVI Decompressor (VFW decompressors wrapper).
parent ed7a2bab
......@@ -3,12 +3,14 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = quartz.dll
IMPORTS = ole32 oleaut32 advapi32 kernel32 user32
IMPORTS = dsound ddraw msvfw32 ole32 oleaut32 user32 advapi32 kernel32
EXTRALIBS = -lstrmiids -luuid $(LIBUNICODE)
C_SRCS = \
avidec.c \
avisplit.c \
control.c \
dsoundrender.c \
enumfilters.c \
enummedia.c \
enummoniker.c \
......@@ -21,7 +23,8 @@ C_SRCS = \
memallocator.c \
pin.c \
regsvr.c \
systemclock.c
systemclock.c \
videorenderer.c
RC_SRCS = version.rc
......
/*
* AVI Decompressor (VFW decompressors wrapper)
*
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "quartz_private.h"
#include "control_private.h"
#include "pin.h"
#include "uuids.h"
#include "aviriff.h"
#include "mmreg.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "strmif.h"
#include "vfwmsgs.h"
#include "evcode.h"
#include "vfw.h"
/* #include "fourcc.h" */
/* #include "avcodec.h" */
#include <assert.h>
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
static const IBaseFilterVtbl AVIDec_Vtbl;
static const IPinVtbl AVIDec_InputPin_Vtbl;
static const IMemInputPinVtbl MemInputPin_Vtbl;
static const IPinVtbl AVIDec_OutputPin_Vtbl;
typedef struct AVIDecImpl
{
const IBaseFilterVtbl * lpVtbl;
ULONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
IPin ** ppPins;
HIC hvid;
int init;
} AVIDecImpl;
static DWORD AVIDec_SendSampleData(AVIDecImpl* This, LPBYTE data, DWORD size)
{
VIDEOINFOHEADER* format;
AM_MEDIA_TYPE amt;
BITMAPINFOHEADER bi;
HRESULT hr;
DWORD res;
IMediaSample* pSample = NULL;
DWORD cbDstStream;
LPBYTE pbDstStream;
hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
if (FAILED(hr)) {
ERR("Unable to retreive media type\n");
goto error;
}
format = (VIDEOINFOHEADER*)amt.pbFormat;
/* Fill a bitmap header for output */
bi.biSize = sizeof(bi);
bi.biWidth = format->bmiHeader.biWidth;
bi.biHeight = format->bmiHeader.biHeight;
bi.biPlanes = 1;
bi.biBitCount = format->bmiHeader.biBitCount;
bi.biCompression = 0;
bi.biSizeImage = bi.biWidth * bi.biHeight * bi.biBitCount / 8;
hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->ppPins[1], &pSample, NULL, NULL, 0);
if (FAILED(hr)) {
ERR("Unable to get delivery buffer (%lx)\n", hr);
goto error;
}
hr = IMediaSample_SetActualDataLength(pSample, 0);
assert(hr == S_OK);
hr = IMediaSample_GetPointer(pSample, &pbDstStream);
if (FAILED(hr)) {
ERR("Unable to get pointer to buffer (%lx)\n", hr);
goto error;
}
cbDstStream = IMediaSample_GetSize(pSample);
if (cbDstStream < bi.biSizeImage) {
ERR("Sample size is too small %ld < %ld\n", cbDstStream, bi.biSizeImage);
hr = E_FAIL;
goto error;
}
res = ICDecompress(This->hvid, 0, &format->bmiHeader, data, &bi, pbDstStream);
if (res != ICERR_OK)
ERR("Error occured during the decompression (%lx)\n", res);
hr = OutputPin_SendSample((OutputPin*)This->ppPins[1], pSample);
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
ERR("Error sending sample (%lx)\n", hr);
goto error;
}
return S_OK;
error:
/* If we have a sample that has not been delivered, release it */
if (pSample)
IMediaSample_Release(pSample);
return hr;
}
static HRESULT AVIDec_Sample(LPVOID iface, IMediaSample * pSample)
{
ICOM_THIS(AVIDecImpl, iface);
LPBYTE pbSrcStream = NULL;
long cbSrcStream = 0;
REFERENCE_TIME tStart, tStop;
HRESULT hr;
TRACE("%p %p\n", iface, pSample);
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%lx)\n", hr);
return hr;
}
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
if (FAILED(hr))
ERR("Cannot get sample time (%lx)\n", hr);
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream);
#if 0 /* For debugging purpose */
{
int i;
for(i = 0; i < cbSrcStream; i++)
{
if ((i!=0) && !(i%16))
DPRINTF("\n");
DPRINTF("%02x ", pbSrcStream[i]);
}
DPRINTF("\n");
}
#endif
AVIDec_SendSampleData(This, pbSrcStream, cbSrcStream);
/* We have finished with the incoming sample, we must release it now */
IMediaSample_Release(pSample);
return S_OK;
}
static HRESULT AVIDec_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
{
AVIDecImpl* pAVIDec = (AVIDecImpl*)iface;
TRACE("%p\n", iface);
dump_AM_MEDIA_TYPE(pmt);
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((char*)&pmt->subtype)+4, ((char*)&MEDIATYPE_Video)+4, sizeof(GUID)-4)) && /* Check root (GUID w/o FOURCC) */
(IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)))
{
HIC drv;
VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
drv = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
if (drv)
{
AM_MEDIA_TYPE* outpmt = &((OutputPin*)pAVIDec->ppPins[1])->pin.mtCurrent;
const CLSID* outsubtype;
switch(format->bmiHeader.biBitCount)
{
case 32: outsubtype = &MEDIATYPE_Video; break;
case 24: outsubtype = &MEDIASUBTYPE_RGB24; break;
case 16: outsubtype = &MEDIASUBTYPE_RGB565; break;
case 8: outsubtype = &MEDIASUBTYPE_RGB8; break;
default:
FIXME("Depth %d not supported\n", format->bmiHeader.biBitCount);
ICClose(drv);
return S_FALSE;
}
CopyMediaType( outpmt, pmt);
outpmt->subtype = *outsubtype;
pAVIDec->hvid = drv;
pAVIDec->init = 1;
TRACE("Connection accepted\n");
return S_OK;
}
TRACE("Unable to find a suitable VFW decompressor\n");
}
TRACE("Connection refused\n");
return S_FALSE;
}
static HRESULT AVIDec_Output_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
{
AVIDecImpl* pAVIDec = (AVIDecImpl*)iface;
AM_MEDIA_TYPE* outpmt = &((OutputPin*)pAVIDec->ppPins[1])->pin.mtCurrent;
TRACE("%p\n", iface);
if (IsEqualIID(&pmt->majortype, &outpmt->majortype) && IsEqualIID(&pmt->subtype, &outpmt->subtype))
return S_OK;
return S_FALSE;
}
static HRESULT AVIDec_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
InputPin * pPinImpl;
*ppPin = NULL;
if (pPinInfo->dir != PINDIR_INPUT)
{
ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
return E_INVALIDARG;
}
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
if (!pPinImpl)
return E_OUTOFMEMORY;
TRACE("QA : %p %p\n", pQueryAccept, AVIDec_Input_QueryAccept);
if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &AVIDec_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
return E_FAIL;
}
HRESULT AVIDec_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
OutputPin * pPinImpl;
*ppPin = NULL;
if (pPinInfo->dir != PINDIR_OUTPUT)
{
ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir);
return E_INVALIDARG;
}
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &AVIDec_OutputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
return E_FAIL;
}
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
PIN_INFO piInput;
PIN_INFO piOutput;
AVIDecImpl * pAVIDec;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
pAVIDec = CoTaskMemAlloc(sizeof(AVIDecImpl));
pAVIDec->lpVtbl = &AVIDec_Vtbl;
pAVIDec->refCount = 1;
InitializeCriticalSection(&pAVIDec->csFilter);
pAVIDec->state = State_Stopped;
pAVIDec->pClock = NULL;
pAVIDec->init = 0;
ZeroMemory(&pAVIDec->filterInfo, sizeof(FILTER_INFO));
pAVIDec->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *));
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pAVIDec;
strncpyW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = (IBaseFilter *)pAVIDec;
strncpyW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
hr = AVIDec_InputPin_Construct(&piInput, AVIDec_Sample, (LPVOID)pAVIDec, AVIDec_Input_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[0]);
if (SUCCEEDED(hr))
{
hr = AVIDec_OutputPin_Construct(&piOutput, NULL, NULL, AVIDec_Output_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[1]);
if (FAILED(hr))
ERR("Cannot create output pin (%lx)\n", hr);
*ppv = (LPVOID)pAVIDec;
}
else
{
CoTaskMemFree(pAVIDec->ppPins);
DeleteCriticalSection(&pAVIDec->csFilter);
CoTaskMemFree(pAVIDec);
}
return hr;
}
static HRESULT WINAPI AVIDec_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IPersist))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IMediaFilter))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = (LPVOID)This;
if (*ppv)
{
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI AVIDec_AddRef(IBaseFilter * iface)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI AVIDec_Release(IBaseFilter * iface)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
if (!InterlockedDecrement(&This->refCount))
{
ULONG i;
DeleteCriticalSection(&This->csFilter);
IReferenceClock_Release(This->pClock);
for (i = 0; i < 2; i++)
IPin_Release(This->ppPins[i]);
HeapFree(GetProcessHeap(), 0, This->ppPins);
This->lpVtbl = NULL;
if (This->hvid)
ICClose(This->hvid);
TRACE("Destroying AVI Decompressor\n");
CoTaskMemFree(This);
return 0;
}
else
return This->refCount;
}
/** IPersist methods **/
static HRESULT WINAPI AVIDec_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_AVIDec;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI AVIDec_Stop(IBaseFilter * iface)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Stopped;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI AVIDec_Pause(IBaseFilter * iface)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Paused;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI AVIDec_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
{
HRESULT hr = S_OK;
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
{
This->rtStreamStart = tStart;
This->state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI AVIDec_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI AVIDec_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
EnterCriticalSection(&This->csFilter);
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->pClock = pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI AVIDec_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static HRESULT WINAPI AVIDec_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
ENUMPINDETAILS epd;
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
epd.cPins = 2; /* input and output pins */
epd.ppPins = This->ppPins;
return IEnumPinsImpl_Construct(&epd, ppEnum);
}
static HRESULT WINAPI AVIDec_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin);
FIXME("AVISplitter::FindPin(...)\n");
/* FIXME: critical section */
return E_NOTIMPL;
}
static HRESULT WINAPI AVIDec_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
strcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
static HRESULT WINAPI AVIDec_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
HRESULT hr = S_OK;
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
EnterCriticalSection(&This->csFilter);
{
if (pName)
strcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = '\0';
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI AVIDec_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
ICOM_THIS(AVIDecImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl AVIDec_Vtbl =
{
AVIDec_QueryInterface,
AVIDec_AddRef,
AVIDec_Release,
AVIDec_GetClassID,
AVIDec_Stop,
AVIDec_Pause,
AVIDec_Run,
AVIDec_GetState,
AVIDec_SetSyncSource,
AVIDec_GetSyncSource,
AVIDec_EnumPins,
AVIDec_FindPin,
AVIDec_QueryFilterInfo,
AVIDec_JoinFilterGraph,
AVIDec_QueryVendorInfo
};
static const IPinVtbl AVIDec_InputPin_Vtbl =
{
InputPin_QueryInterface,
IPinImpl_AddRef,
InputPin_Release,
InputPin_Connect,
InputPin_ReceiveConnection,
IPinImpl_Disconnect,
IPinImpl_ConnectedTo,
IPinImpl_ConnectionMediaType,
IPinImpl_QueryPinInfo,
IPinImpl_QueryDirection,
IPinImpl_QueryId,
IPinImpl_QueryAccept,
IPinImpl_EnumMediaTypes,
IPinImpl_QueryInternalConnections,
InputPin_EndOfStream,
InputPin_BeginFlush,
InputPin_EndFlush,
InputPin_NewSegment
};
HRESULT WINAPI AVIDec_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
{
ICOM_THIS(IPinImpl, iface);
ENUMMEDIADETAILS emd;
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
emd.cMediaTypes = 1;
emd.pMediaTypes = &This->mtCurrent;
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
}
HRESULT WINAPI AVIDec_Output_Disconnect(IPin * iface)
{
OutputPin* This = (OutputPin*)iface;
HRESULT hr;
AVIDecImpl* pAVIDec = (AVIDecImpl*)This->pin.pinInfo.pFilter;
TRACE("(%p/%p)->()\n", This, iface);
hr = OutputPin_Disconnect(iface);
if (hr == S_OK)
{
ICClose(pAVIDec->hvid);
pAVIDec->hvid = 0;
}
return hr;
}
static const IPinVtbl AVIDec_OutputPin_Vtbl =
{
OutputPin_QueryInterface,
IPinImpl_AddRef,
OutputPin_Release,
OutputPin_Connect,
OutputPin_ReceiveConnection,
AVIDec_Output_Disconnect,
IPinImpl_ConnectedTo,
IPinImpl_ConnectionMediaType,
IPinImpl_QueryPinInfo,
IPinImpl_QueryDirection,
IPinImpl_QueryId,
IPinImpl_QueryAccept,
AVIDec_Output_EnumMediaTypes,
IPinImpl_QueryInternalConnections,
OutputPin_EndOfStream,
OutputPin_BeginFlush,
OutputPin_EndFlush,
OutputPin_NewSegment
};
static const IMemInputPinVtbl MemInputPin_Vtbl =
{
MemInputPin_QueryInterface,
MemInputPin_AddRef,
MemInputPin_Release,
MemInputPin_GetAllocator,
MemInputPin_NotifyAllocator,
MemInputPin_GetAllocatorRequirements,
MemInputPin_Receive,
MemInputPin_ReceiveMultiple,
MemInputPin_ReceiveCanBlock
};
/*
* Direct Sound Audio Renderer
*
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "quartz_private.h"
#include "control_private.h"
#include "pin.h"
#include "uuids.h"
#include "mmreg.h"
#include "vfwmsgs.h"
#include "fourcc.h"
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "evcode.h"
#include "strmif.h"
#include "dsound.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const IBaseFilterVtbl DSoundRender_Vtbl;
static const IPinVtbl DSoundRender_InputPin_Vtbl;
static const IMemInputPinVtbl MemInputPin_Vtbl;
static const IBasicAudioVtbl IBasicAudio_Vtbl;
typedef struct DSoundRenderImpl
{
const IBaseFilterVtbl * lpVtbl;
const IBasicAudioVtbl *IBasicAudio_vtbl;
ULONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
IMediaEventSink * pEventSink;
InputPin * pInputPin;
IPin ** ppPins;
LPDIRECTSOUND dsound;
LPDIRECTSOUNDBUFFER dsbuffer;
DWORD write_pos;
int init;
} DSoundRenderImpl;
static HRESULT DSoundRender_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
InputPin * pPinImpl;
*ppPin = NULL;
if (pPinInfo->dir != PINDIR_INPUT)
{
ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
return E_INVALIDARG;
}
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &DSoundRender_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
return E_FAIL;
}
#define DSBUFFERSIZE 8192
static HRESULT DSoundRender_CreateSoundBuffer(IBaseFilter * iface)
{
HRESULT hr;
WAVEFORMATEX wav_fmt;
AM_MEDIA_TYPE amt;
WAVEFORMATEX* format;
DSBUFFERDESC buf_desc;
ICOM_THIS(DSoundRenderImpl, iface);
hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
if (FAILED(hr)) {
ERR("Unable to retreive media type\n");
return hr;
}
TRACE("MajorType %s\n", debugstr_guid(&amt.majortype));
TRACE("SubType %s\n", debugstr_guid(&amt.subtype));
TRACE("Format %s\n", debugstr_guid(&amt.formattype));
TRACE("Size %ld\n", amt.cbFormat);
dump_AM_MEDIA_TYPE(&amt);
format = (WAVEFORMATEX*)amt.pbFormat;
TRACE("wFormatTag = %x %x\n", format->wFormatTag, WAVE_FORMAT_PCM);
TRACE("nChannels = %d\n", format->nChannels);
TRACE("nSamplesPerSec = %lu\n", format->nSamplesPerSec);
TRACE("nAvgBytesPerSec = %lu\n", format->nAvgBytesPerSec);
TRACE("nBlockAlign = %d\n", format->nBlockAlign);
TRACE("wBitsPerSample = %d\n", format->wBitsPerSample);
TRACE("cbSize = %d\n", format->cbSize);
hr = DirectSoundCreate(NULL, &This->dsound, NULL);
if (FAILED(hr)) {
ERR("Cannot create Direct Sound object\n");
return hr;
}
wav_fmt = *format;
wav_fmt.cbSize = 0;
memset(&buf_desc,0,sizeof(DSBUFFERDESC));
buf_desc.dwSize = sizeof(DSBUFFERDESC);
buf_desc.dwBufferBytes = DSBUFFERSIZE;
buf_desc.lpwfxFormat = &wav_fmt;
hr = IDirectSound_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
if (FAILED(hr)) {
ERR("Can't create sound buffer !\n");
return hr;
}
This->write_pos = 0;
return hr;
}
static DWORD DSoundRender_SendSampleData(DSoundRenderImpl* This, LPBYTE data, DWORD size)
{
HRESULT result;
LPBYTE lpbuf1 = NULL;
LPBYTE lpbuf2 = NULL;
DWORD dwsize1 = 0;
DWORD dwsize2 = 0;
static int init_;
DWORD size2;
DWORD play_pos,buf_free;
while (1)
{
result=IDirectSoundBuffer_GetCurrentPosition(This->dsbuffer, &play_pos, NULL);
if (result != DS_OK) {
ERR("Error GetCurrentPosition: %lx\n", result);
break;
}
if (This->write_pos < play_pos)
buf_free = play_pos-This->write_pos;
else
buf_free = DSBUFFERSIZE - This->write_pos + play_pos;
size2 = min(buf_free, size);
result = IDirectSoundBuffer_Lock(This->dsbuffer, This->write_pos, size2, &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
if (result != DS_OK) {
ERR("Unable to lock sound buffer !\n");
break;
}
TRACE("write_pos=%ld, size=%ld, sz1=%ld, sz2=%ld\n", This->write_pos, size2, dwsize1, dwsize2);
memcpy(lpbuf1, data, dwsize1);
if (dwsize2) {
memcpy(lpbuf2, data + dwsize1, dwsize2);
}
result = IDirectSoundBuffer_Unlock(This->dsbuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
if (result != DS_OK)
ERR("Unable to unlock sound buffer !\n");
if (!init_)
{
result = IDirectSoundBuffer_Play(This->dsbuffer, 0, 0, DSBPLAY_LOOPING);
if (result != DS_OK) {
ERR("Can't start playing !\n");
}
}
size -= dwsize1 + dwsize2;
data += dwsize1 + dwsize2;
This->write_pos = (This->write_pos + dwsize1 + dwsize2) % DSBUFFERSIZE;
if (!size)
break;
Sleep(10);
}
return 0;
}
static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
{
ICOM_THIS(DSoundRenderImpl, iface);
LPBYTE pbSrcStream = NULL;
long cbSrcStream = 0;
REFERENCE_TIME tStart, tStop;
HRESULT hr;
TRACE("%p %p\n", iface, pSample);
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%lx)\n", hr);
return hr;
}
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
if (FAILED(hr))
ERR("Cannot get sample time (%lx)\n", hr);
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream);
#if 0 /* For debugging purpose */
{
int i;
for(i = 0; i < cbSrcStream; i++)
{
if ((i!=0) && !(i%16))
DPRINTF("\n");
DPRINTF("%02x ", pbSrcStream[i]);
}
DPRINTF("\n");
}
#endif
if (!This->init)
{
This->init = 1;
hr = DSoundRender_CreateSoundBuffer(iface);
if (FAILED(hr))
{
ERR("Unable to create DSound buffer\n");
}
}
DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream);
/* We have finished with the incoming sample, we must release it now */
IMediaSample_Release(pSample);
return S_OK;
}
static HRESULT DSoundRender_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
{
WAVEFORMATEX* format = (WAVEFORMATEX*)pmt->pbFormat;
TRACE("wFormatTag = %x %x\n", format->wFormatTag, WAVE_FORMAT_PCM);
TRACE("nChannels = %d\n", format->nChannels);
TRACE("nSamplesPerSec = %ld\n", format->nAvgBytesPerSec);
TRACE("nAvgBytesPerSec = %ld\n", format->nAvgBytesPerSec);
TRACE("nBlockAlign = %d\n", format->nBlockAlign);
TRACE("wBitsPerSample = %d\n", format->wBitsPerSample);
if (IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_PCM))
return S_OK;
return S_FALSE;
}
HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
PIN_INFO piInput;
DSoundRenderImpl * pDSoundRender;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl));
pDSoundRender->lpVtbl = &DSoundRender_Vtbl;
pDSoundRender->IBasicAudio_vtbl = &IBasicAudio_Vtbl;
pDSoundRender->refCount = 1;
InitializeCriticalSection(&pDSoundRender->csFilter);
pDSoundRender->state = State_Stopped;
pDSoundRender->pClock = NULL;
pDSoundRender->init = 0;
ZeroMemory(&pDSoundRender->filterInfo, sizeof(FILTER_INFO));
pDSoundRender->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pDSoundRender;
strncpyW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = DSoundRender_InputPin_Construct(&piInput, DSoundRender_Sample, (LPVOID)pDSoundRender, DSoundRender_QueryAccept, &pDSoundRender->csFilter, (IPin **)&pDSoundRender->pInputPin);
if (SUCCEEDED(hr))
{
pDSoundRender->ppPins[0] = (IPin *)pDSoundRender->pInputPin;
*ppv = (LPVOID)pDSoundRender;
}
else
{
CoTaskMemFree(pDSoundRender->ppPins);
DeleteCriticalSection(&pDSoundRender->csFilter);
CoTaskMemFree(pDSoundRender);
}
return hr;
}
static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p, %p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IPersist))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IMediaFilter))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = (LPVOID)&(This->IBasicAudio_vtbl);
if (*ppv)
{
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI DSoundRender_AddRef(IBaseFilter * iface)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
if (!InterlockedDecrement(&This->refCount))
{
DeleteCriticalSection(&This->csFilter);
if (This->pClock)
IReferenceClock_Release(This->pClock);
IPin_Release(This->ppPins[0]);
HeapFree(GetProcessHeap(), 0, This->ppPins);
This->lpVtbl = NULL;
This->IBasicAudio_vtbl = NULL;
TRACE("Destroying Audio Renderer\n");
CoTaskMemFree(This);
return 0;
}
else
return This->refCount;
}
/** IPersist methods **/
static HRESULT WINAPI DSoundRender_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_DSoundRender;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI DSoundRender_Stop(IBaseFilter * iface)
{
HRESULT hr = S_OK;
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Stopped;
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface)
{
HRESULT hr = S_OK;
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Paused;
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI DSoundRender_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
{
HRESULT hr = S_OK;
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
{
This->rtStreamStart = tStart;
This->state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI DSoundRender_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
EnterCriticalSection(&This->csFilter);
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->pClock = pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI DSoundRender_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static HRESULT WINAPI DSoundRender_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
ENUMPINDETAILS epd;
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
epd.cPins = 1; /* input pin */
epd.ppPins = This->ppPins;
return IEnumPinsImpl_Construct(&epd, ppEnum);
}
static HRESULT WINAPI DSoundRender_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_w(Id), ppPin);
FIXME("DSoundRender::FindPin(...)\n");
/* FIXME: critical section */
return E_NOTIMPL;
}
static HRESULT WINAPI DSoundRender_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
strcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
static HRESULT WINAPI DSoundRender_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
HRESULT hr;
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
EnterCriticalSection(&This->csFilter);
{
if (pName)
strcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = '\0';
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
hr = IFilterGraph_QueryInterface(pGraph, &IID_IMediaEventSink, (LPVOID*)&This->pEventSink);
}
LeaveCriticalSection(&This->csFilter);
return hr;
}
static HRESULT WINAPI DSoundRender_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
ICOM_THIS(DSoundRenderImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl DSoundRender_Vtbl =
{
DSoundRender_QueryInterface,
DSoundRender_AddRef,
DSoundRender_Release,
DSoundRender_GetClassID,
DSoundRender_Stop,
DSoundRender_Pause,
DSoundRender_Run,
DSoundRender_GetState,
DSoundRender_SetSyncSource,
DSoundRender_GetSyncSource,
DSoundRender_EnumPins,
DSoundRender_FindPin,
DSoundRender_QueryFilterInfo,
DSoundRender_JoinFilterGraph,
DSoundRender_QueryVendorInfo
};
static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
{
/* FIXME: critical section */
InputPin* This = (InputPin*)iface;
TRACE("(%p/%p)->()\n", This, iface);
return IMediaEventSink_Notify(((DSoundRenderImpl*)This->pin.pinInfo.pFilter)->pEventSink, EC_COMPLETE, S_OK, 0);
}
static const IPinVtbl DSoundRender_InputPin_Vtbl =
{
InputPin_QueryInterface,
IPinImpl_AddRef,
InputPin_Release,
InputPin_Connect,
InputPin_ReceiveConnection,
IPinImpl_Disconnect,
IPinImpl_ConnectedTo,
IPinImpl_ConnectionMediaType,
IPinImpl_QueryPinInfo,
IPinImpl_QueryDirection,
IPinImpl_QueryId,
IPinImpl_QueryAccept,
IPinImpl_EnumMediaTypes,
IPinImpl_QueryInternalConnections,
DSoundRender_InputPin_EndOfStream,
InputPin_BeginFlush,
InputPin_EndFlush,
InputPin_NewSegment
};
static const IMemInputPinVtbl MemInputPin_Vtbl =
{
MemInputPin_QueryInterface,
MemInputPin_AddRef,
MemInputPin_Release,
MemInputPin_GetAllocator,
MemInputPin_NotifyAllocator,
MemInputPin_GetAllocatorRequirements,
MemInputPin_Receive,
MemInputPin_ReceiveMultiple,
MemInputPin_ReceiveCanBlock
};
/*** IUnknown methods ***/
static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface,
REFIID riid,
LPVOID*ppvObj) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
return DSoundRender_QueryInterface((IBaseFilter*)This, riid, ppvObj);
}
static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return DSoundRender_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return DSoundRender_Release((IBaseFilter*)This);
}
/*** IDispatch methods ***/
static HRESULT WINAPI Basicaudio_GetTypeInfoCount(IBasicAudio *iface,
UINT*pctinfo) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
return S_OK;
}
static HRESULT WINAPI Basicaudio_GetTypeInfo(IBasicAudio *iface,
UINT iTInfo,
LCID lcid,
ITypeInfo**ppTInfo) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
return S_OK;
}
static HRESULT WINAPI Basicaudio_GetIDsOfNames(IBasicAudio *iface,
REFIID riid,
LPOLESTR*rgszNames,
UINT cNames,
LCID lcid,
DISPID*rgDispId) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
return S_OK;
}
static HRESULT WINAPI Basicaudio_Invoke(IBasicAudio *iface,
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS*pDispParams,
VARIANT*pVarResult,
EXCEPINFO*pExepInfo,
UINT*puArgErr) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
return S_OK;
}
/*** IBasicAudio methods ***/
static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface,
long lVolume) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, lVolume);
return S_OK;
}
static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface,
long *plVolume) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, plVolume);
return S_OK;
}
static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface,
long lBalance) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, lBalance);
return S_OK;
}
static HRESULT WINAPI Basicaudio_get_Balance(IBasicAudio *iface,
long *plBalance) {
ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, plBalance);
return S_OK;
}
static const IBasicAudioVtbl IBasicAudio_Vtbl =
{
Basicaudio_QueryInterface,
Basicaudio_AddRef,
Basicaudio_Release,
Basicaudio_GetTypeInfoCount,
Basicaudio_GetTypeInfo,
Basicaudio_GetIDsOfNames,
Basicaudio_Invoke,
Basicaudio_put_Volume,
Basicaudio_get_Volume,
Basicaudio_put_Balance,
Basicaudio_get_Balance
};
......@@ -66,7 +66,9 @@ static const struct object_creation_info object_creation[] =
{ &CLSID_AsyncReader, AsyncReader_create },
{ &CLSID_MemoryAllocator, StdMemAllocator_create },
{ &CLSID_AviSplitter, AVISplitter_create },
{ &CLSID_VideoRenderer, VideoRenderer_create },
{ &CLSID_DSoundRender, DSoundRender_create },
{ &CLSID_AVIDec, AVIDec_create },
{ &CLSID_SystemClock, &QUARTZ_CreateSystemClock }
};
......
......@@ -44,6 +44,9 @@ HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj);
HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT StdMemAllocator_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv);
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum);
......
......@@ -527,6 +527,42 @@ static struct regsvr_coclass const coclass_list[] = {
"quartz.dll",
"Both"
},
{ &CLSID_MemoryAllocator,
"Memory Allocator",
NULL,
"quartz.dll",
"Both"
},
{ &CLSID_AsyncReader,
"File Source Filter",
NULL,
"quartz.dll",
"Both"
},
{ &CLSID_AviSplitter,
"AVI Splitter",
NULL,
"quartz.dll",
"Both"
},
{ &CLSID_AVIDec,
"AVI Decompressor",
NULL,
"quartz.dll",
"Both"
},
{ &CLSID_DSoundRender,
"Direct Sound Audio Renderer",
NULL,
"quartz.dll",
"Both"
},
{ &CLSID_VideoRenderer,
"Video Renderer",
NULL,
"quartz.dll",
"Both"
},
{ NULL } /* list terminator */
};
......
/*
* Video Renderer (Fullscreen and Windowed using Direct Draw)
*
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "quartz_private.h"
#include "control_private.h"
#include "pin.h"
#include "uuids.h"
#include "mmreg.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "fourcc.h"
#include "windef.h"
#include "winbase.h"
#include "dshow.h"
#include "strmif.h"
#include "ddraw.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const IBaseFilterVtbl VideoRenderer_Vtbl;
static IBasicVideoVtbl IBasicVideo_VTable;
static IVideoWindowVtbl IVideoWindow_VTable;
static const IPinVtbl VideoRenderer_InputPin_Vtbl;
typedef struct VideoRendererImpl
{
const IBaseFilterVtbl * lpVtbl;
IBasicVideoVtbl * IBasicVideo_vtbl;
IVideoWindowVtbl * IVideoWindow_vtbl;
ULONG refCount;
CRITICAL_SECTION csFilter;
FILTER_STATE state;
REFERENCE_TIME rtStreamStart;
IReferenceClock * pClock;
FILTER_INFO filterInfo;
InputPin * pInputPin;
IPin ** ppPins;
LPDIRECTDRAW ddraw;
LPDIRECTDRAWSURFACE surface;
LPDIRECTDRAWSURFACE backbuffer;
int init;
} VideoRendererImpl;
static const IMemInputPinVtbl MemInputPin_Vtbl =
{
MemInputPin_QueryInterface,
MemInputPin_AddRef,
MemInputPin_Release,
MemInputPin_GetAllocator,
MemInputPin_NotifyAllocator,
MemInputPin_GetAllocatorRequirements,
MemInputPin_Receive,
MemInputPin_ReceiveMultiple,
MemInputPin_ReceiveCanBlock
};
static HRESULT VideoRenderer_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
InputPin * pPinImpl;
*ppPin = NULL;
if (pPinInfo->dir != PINDIR_INPUT)
{
ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
return E_INVALIDARG;
}
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &VideoRenderer_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
return E_FAIL;
}
static HRESULT VideoRenderer_CreatePrimarySurface(IBaseFilter * iface)
{
HRESULT hr;
DDSURFACEDESC sdesc;
DDSCAPS ddscaps;
ICOM_THIS(VideoRendererImpl, iface);
hr = DirectDrawCreate(NULL, &This->ddraw, NULL);
if (FAILED(hr)) {
ERR("Cannot create Direct Draw object\n");
return hr;
}
hr = IDirectDraw_SetCooperativeLevel(This->ddraw, NULL, DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE);
if (FAILED(hr)) {
ERR("Cannot set fulscreen mode\n");
return hr;
}
sdesc.dwSize = sizeof(sdesc);
sdesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
sdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
sdesc.dwBackBufferCount = 1;
hr = IDirectDraw_CreateSurface(This->ddraw, &sdesc, &This->surface, NULL);
if (FAILED(hr)) {
ERR("Cannot create surface\n");
return hr;
}
hr = IDirectDrawSurface_GetSurfaceDesc(This->surface, &sdesc);
if (FAILED(hr)) {
ERR("Cannot get surface information\n");
return hr;
}
TRACE("Width = %ld\n", sdesc.dwWidth);
TRACE("Height = %ld\n", sdesc.dwHeight);
TRACE("Pitch = %ld\n", sdesc.u1.lPitch);
TRACE("Depth = %ld\n", sdesc.ddpfPixelFormat.u1.dwRGBBitCount);
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = IDirectDrawSurface_GetAttachedSurface(This->surface, &ddscaps, &This->backbuffer);
if (FAILED(hr)) {
ERR("Cannot get backbuffer\n");
return hr;
}
return S_OK;
}
static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
{
VIDEOINFOHEADER* format;
AM_MEDIA_TYPE amt;
HRESULT hr = S_OK;
int i = 0;
int j = 0;
LPBYTE ptr;
DDSURFACEDESC sdesc;
int width;
int height;
LPBYTE palette = NULL;
TRACE("%p %p %ld\n", This, data, size);
sdesc.dwSize = sizeof(sdesc);
hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
if (FAILED(hr)) {
ERR("Unable to retreive media type\n");
return hr;
}
format = (VIDEOINFOHEADER*)amt.pbFormat;
TRACE("biSize = %ld\n", format->bmiHeader.biSize);
TRACE("biWidth = %ld\n", format->bmiHeader.biWidth);
TRACE("biHeigth = %ld\n", format->bmiHeader.biHeight);
TRACE("biPlanes = %d\n", format->bmiHeader.biPlanes);
TRACE("biBitCount = %d\n", format->bmiHeader.biBitCount);
TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(format->bmiHeader.biCompression), 4));
TRACE("biSizeImage = %ld\n", format->bmiHeader.biSizeImage);
width = format->bmiHeader.biWidth;
height = format->bmiHeader.biHeight;
palette = ((LPBYTE)&format->bmiHeader) + format->bmiHeader.biSize;
hr = IDirectDrawSurface_Lock(This->backbuffer, NULL, &sdesc, DDLOCK_WRITEONLY, NULL);
if (FAILED(hr)) {
ERR("Cannot lock backbuffer\n");
return hr;
}
ptr = sdesc.lpSurface;
/* FIXME: We may use Direct Draw services to do the conversion for us */
if ((sdesc.ddpfPixelFormat.u1.dwRGBBitCount == 24) || (sdesc.ddpfPixelFormat.u1.dwRGBBitCount == 32))
{
if (format->bmiHeader.biBitCount == 8)
{
int psz = sdesc.ddpfPixelFormat.u1.dwRGBBitCount == 32 ? 4 : 3;
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
{
*(ptr + i*psz + 0 + j * sdesc.u1.lPitch) = palette[*(data + i + 0 + (height-1-j) * width)*4 + 0];
*(ptr + i*psz + 1 + j * sdesc.u1.lPitch) = palette[*(data + i + 0 + (height-1-j) * width)*4 + 1];
*(ptr + i*psz + 2 + j * sdesc.u1.lPitch) = palette[*(data + i + 0 + (height-1-j) * width)*4 + 2];
if (psz == 4)
*(ptr + i*psz + 3 + j * sdesc.u1.lPitch) = 0xFF;
}
}
else
FIXME("Source size with a depths other than paletted 8 bits are not yet supported\n");
}
else
FIXME("Destination depths with a depth other than 24 or 32 bits are not yet supported\n");
hr = IDirectDrawSurface_Unlock(This->backbuffer, NULL);
if (FAILED(hr)) {
ERR("Cannot unlock backbuffer\n");
return hr;
}
hr = IDirectDrawSurface_Flip(This->surface, NULL, DDFLIP_WAIT);
if (FAILED(hr)) {
ERR("Cannot unlock backbuffer\n");
return hr;
}
return S_OK;
}
static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
{
ICOM_THIS(VideoRendererImpl, iface);
LPBYTE pbSrcStream = NULL;
long cbSrcStream = 0;
REFERENCE_TIME tStart, tStop;
HRESULT hr;
TRACE("%p %p\n", iface, pSample);
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%lx)\n", hr);
return hr;
}
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
if (FAILED(hr))
ERR("Cannot get sample time (%lx)\n", hr);
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
TRACE("val %p %ld\n", pbSrcStream, cbSrcStream);
#if 0 /* For debugging purpose */
{
int i;
for(i = 0; i < cbSrcStream; i++)
{
if ((i!=0) && !(i%16))
DPRINTF("\n");
DPRINTF("%02x ", pbSrcStream[i]);
}
DPRINTF("\n");
}
#endif
if (!This->init)
{
This->init = 1;
hr = VideoRenderer_CreatePrimarySurface(iface);
if (FAILED(hr))
{
ERR("Unable to create primary surface\n");
}
}
VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
/* We have finished with the incoming sample, we must release it now */
IMediaSample_Release(pSample);
return S_OK;
}
static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
{
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32)) ||
(IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24)) ||
(IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565)) ||
(IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)))
return S_OK;
return S_FALSE;
}
HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
PIN_INFO piInput;
VideoRendererImpl * pVideoRenderer;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
*ppv = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl));
pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl;
pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable;
pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable;
pVideoRenderer->refCount = 1;
InitializeCriticalSection(&pVideoRenderer->csFilter);
pVideoRenderer->state = State_Stopped;
pVideoRenderer->pClock = NULL;
pVideoRenderer->init = 0;
ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
pVideoRenderer->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
strncpyW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = VideoRenderer_InputPin_Construct(&piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, &pVideoRenderer->csFilter, (IPin **)&pVideoRenderer->pInputPin);
if (SUCCEEDED(hr))
{
pVideoRenderer->ppPins[0] = (IPin *)pVideoRenderer->pInputPin;
*ppv = (LPVOID)pVideoRenderer;
}
else
{
CoTaskMemFree(pVideoRenderer->ppPins);
DeleteCriticalSection(&pVideoRenderer->csFilter);
CoTaskMemFree(pVideoRenderer);
}
return hr;
}
static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IPersist))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IMediaFilter))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBasicVideo))
*ppv = (LPVOID)&(This->IBasicVideo_vtbl);
else if (IsEqualIID(riid, &IID_IVideoWindow))
*ppv = (LPVOID)&(This->IVideoWindow_vtbl);
if (*ppv)
{
IUnknown_AddRef((IUnknown *)(*ppv));
return S_OK;
}
FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, This->refCount);
return InterlockedIncrement(&This->refCount);
}
static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->() Release from %ld\n", This, iface, This->refCount);
if (!InterlockedDecrement(&This->refCount))
{
DeleteCriticalSection(&This->csFilter);
IReferenceClock_Release(This->pClock);
IPin_Release(This->ppPins[0]);
HeapFree(GetProcessHeap(), 0, This->ppPins);
This->lpVtbl = NULL;
TRACE("Destroying Video Renderer\n");
CoTaskMemFree(This);
return 0;
}
else
return This->refCount;
}
/** IPersist methods **/
static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
*pClsid = CLSID_VideoRenderer;
return S_OK;
}
/** IMediaFilter methods **/
static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Stopped;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
{
This->state = State_Paused;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
{
This->rtStreamStart = tStart;
This->state = State_Running;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
EnterCriticalSection(&This->csFilter);
{
if (This->pClock)
IReferenceClock_Release(This->pClock);
This->pClock = pClock;
if (This->pClock)
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
EnterCriticalSection(&This->csFilter);
{
*ppClock = This->pClock;
IReferenceClock_AddRef(This->pClock);
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
/** IBaseFilter implementation **/
static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
ENUMPINDETAILS epd;
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
epd.cPins = 1; /* input pin */
epd.ppPins = This->ppPins;
return IEnumPinsImpl_Construct(&epd, ppEnum);
}
static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin);
FIXME("VideoRenderer::FindPin(...)\n");
/* FIXME: critical section */
return E_NOTIMPL;
}
static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
strcpyW(pInfo->achName, This->filterInfo.achName);
pInfo->pGraph = This->filterInfo.pGraph;
if (pInfo->pGraph)
IFilterGraph_AddRef(pInfo->pGraph);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
EnterCriticalSection(&This->csFilter);
{
if (pName)
strcpyW(This->filterInfo.achName, pName);
else
*This->filterInfo.achName = '\0';
This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
}
LeaveCriticalSection(&This->csFilter);
return S_OK;
}
static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
{
ICOM_THIS(VideoRendererImpl, iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
return E_NOTIMPL;
}
static const IBaseFilterVtbl VideoRenderer_Vtbl =
{
VideoRenderer_QueryInterface,
VideoRenderer_AddRef,
VideoRenderer_Release,
VideoRenderer_GetClassID,
VideoRenderer_Stop,
VideoRenderer_Pause,
VideoRenderer_Run,
VideoRenderer_GetState,
VideoRenderer_SetSyncSource,
VideoRenderer_GetSyncSource,
VideoRenderer_EnumPins,
VideoRenderer_FindPin,
VideoRenderer_QueryFilterInfo,
VideoRenderer_JoinFilterGraph,
VideoRenderer_QueryVendorInfo
};
static const IPinVtbl VideoRenderer_InputPin_Vtbl =
{
InputPin_QueryInterface,
IPinImpl_AddRef,
InputPin_Release,
InputPin_Connect,
InputPin_ReceiveConnection,
IPinImpl_Disconnect,
IPinImpl_ConnectedTo,
IPinImpl_ConnectionMediaType,
IPinImpl_QueryPinInfo,
IPinImpl_QueryDirection,
IPinImpl_QueryId,
IPinImpl_QueryAccept,
IPinImpl_EnumMediaTypes,
IPinImpl_QueryInternalConnections,
InputPin_EndOfStream,
InputPin_BeginFlush,
InputPin_EndFlush,
InputPin_NewSegment
};
/*** IUnknown methods ***/
static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface,
REFIID riid,
LPVOID*ppvObj) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
}
static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return VideoRenderer_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return VideoRenderer_Release((IBaseFilter*)This);
}
/*** IDispatch methods ***/
static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface,
UINT*pctinfo) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface,
UINT iTInfo,
LCID lcid,
ITypeInfo**ppTInfo) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface,
REFIID riid,
LPOLESTR*rgszNames,
UINT cNames,
LCID lcid,
DISPID*rgDispId) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
return S_OK;
}
static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface,
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS*pDispParams,
VARIANT*pVarResult,
EXCEPINFO*pExepInfo,
UINT*puArgErr) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
return S_OK;
}
/*** IBasicVideo methods ***/
static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface,
REFTIME *pAvgTimePerFrame) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface,
long *pBitRate) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface,
long *pBitErrorRate) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface,
long *pVideoWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVideoWidth);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface,
long *pVideoHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVideoHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface,
long SourceLeft) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceLeft);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface,
long *pSourceLeft) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceLeft);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface,
long SourceWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceWidth);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface,
long *pSourceWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceWidth);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface,
long SourceTop) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceTop);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface,
long *pSourceTop) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceTop);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface,
long SourceHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, SourceHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface,
long *pSourceHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pSourceHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface,
long DestinationLeft) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationLeft);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface,
long *pDestinationLeft) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationLeft);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface,
long DestinationWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationWidth);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface,
long *pDestinationWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationWidth);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface,
long DestinationTop) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationTop);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface,
long *pDestinationTop) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationTop);
return S_OK;
}
static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface,
long DestinationHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, DestinationHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface,
long *pDestinationHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pDestinationHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface,
long Left,
long Top,
long Width,
long Height) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface,
long *pLeft,
long *pTop,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(): stub !!!\n", This, iface);
return S_OK;
}
static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface,
long Left,
long Top,
long Width,
long Height) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface,
long *pLeft,
long *pTop,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(): stub !!!\n", This, iface);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface,
long StartIndex,
long Entries,
long *pRetrieved,
long *pPalette) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%ld, %ld, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
return S_OK;
}
static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
long *pBufferSize,
long *pDIBImage) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pBufferSize, pDIBImage);
return S_OK;
}
static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(): stub !!!\n", This, iface);
return S_OK;
}
static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
TRACE("(%p/%p)->(): stub !!!\n", This, iface);
return S_OK;
}
static IBasicVideoVtbl IBasicVideo_VTable =
{
Basicvideo_QueryInterface,
Basicvideo_AddRef,
Basicvideo_Release,
Basicvideo_GetTypeInfoCount,
Basicvideo_GetTypeInfo,
Basicvideo_GetIDsOfNames,
Basicvideo_Invoke,
Basicvideo_get_AvgTimePerFrame,
Basicvideo_get_BitRate,
Basicvideo_get_BitErrorRate,
Basicvideo_get_VideoWidth,
Basicvideo_get_VideoHeight,
Basicvideo_put_SourceLeft,
Basicvideo_get_SourceLeft,
Basicvideo_put_SourceWidth,
Basicvideo_get_SourceWidth,
Basicvideo_put_SourceTop,
Basicvideo_get_SourceTop,
Basicvideo_put_SourceHeight,
Basicvideo_get_SourceHeight,
Basicvideo_put_DestinationLeft,
Basicvideo_get_DestinationLeft,
Basicvideo_put_DestinationWidth,
Basicvideo_get_DestinationWidth,
Basicvideo_put_DestinationTop,
Basicvideo_get_DestinationTop,
Basicvideo_put_DestinationHeight,
Basicvideo_get_DestinationHeight,
Basicvideo_SetSourcePosition,
Basicvideo_GetSourcePosition,
Basicvideo_SetDefaultSourcePosition,
Basicvideo_SetDestinationPosition,
Basicvideo_GetDestinationPosition,
Basicvideo_SetDefaultDestinationPosition,
Basicvideo_GetVideoSize,
Basicvideo_GetVideoPaletteEntries,
Basicvideo_GetCurrentImage,
Basicvideo_IsUsingDefaultSource,
Basicvideo_IsUsingDefaultDestination
};
/*** IUnknown methods ***/
static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface,
REFIID riid,
LPVOID*ppvObj) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
}
static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return VideoRenderer_AddRef((IBaseFilter*)This);
}
static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->()\n", This, iface);
return VideoRenderer_Release((IBaseFilter*)This);
}
/*** IDispatch methods ***/
static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface,
UINT*pctinfo) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface,
UINT iTInfo,
LCID lcid,
ITypeInfo**ppTInfo) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface,
REFIID riid,
LPOLESTR*rgszNames,
UINT cNames,
LCID lcid,
DISPID*rgDispId) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
return S_OK;
}
static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface,
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS*pDispParams,
VARIANT*pVarResult,
EXCEPINFO*pExepInfo,
UINT*puArgErr) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
return S_OK;
}
/*** IVideoWindow methods ***/
static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface,
BSTR strCaption) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strCaption), strCaption);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface,
BSTR *strCaption) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, strCaption);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface,
long WindowStyle) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowStyle);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface,
long *WindowStyle) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowStyle);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface,
long WindowStyleEx) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowStyleEx);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface,
long *WindowStyleEx) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowStyleEx);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface,
long AutoShow) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, AutoShow);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface,
long *AutoShow) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, AutoShow);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface,
long WindowState) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowState);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface,
long *WindowState) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface,
long BackgroundPalette) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, BackgroundPalette);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface,
long *pBackgroundPalette) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface,
long Visible) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Visible);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface,
long *pVisible) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pVisible);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface,
long Left) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Left);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface,
long *pLeft) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pLeft);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface,
long Width) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Width);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface,
long *pWidth) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pWidth);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface,
long Top) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Top);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface,
long *pTop) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pTop);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface,
long Height) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Height);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pHeight);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface,
OAHWND Owner) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Owner);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface,
OAHWND *Owner) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Owner);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface,
OAHWND Drain) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%08lx): stub !!!\n", This, iface, (DWORD) Drain);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface,
OAHWND *Drain) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, Drain);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface,
long *Color) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, Color);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface,
long Color) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Color);
return S_OK;
}
static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface,
long *FullScreenMode) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode);
return S_OK;
}
static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface,
long FullScreenMode) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, FullScreenMode);
return S_OK;
}
static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface,
long Focus) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, Focus);
return S_OK;
}
static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface,
OAHWND hwnd,
long uMsg,
LONG_PTR wParam,
LONG_PTR lParam) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%08lx, %ld, %08lx, %08lx): stub !!!\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
return S_OK;
}
static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface,
long Left,
long Top,
long Width,
long Height) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld, %ld, %ld, %ld): stub !!!\n", This, iface, Left, Top, Width, Height);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface,
long *pLeft,
long *pTop,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface,
long *pLeft,
long *pTop,
long *pWidth,
long *pHeight) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
return S_OK;
}
static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface,
long HideCursor) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%ld): stub !!!\n", This, iface, HideCursor);
return S_OK;
}
static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface,
long *CursorHidden) {
ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden);
return S_OK;
}
static IVideoWindowVtbl IVideoWindow_VTable =
{
Videowindow_QueryInterface,
Videowindow_AddRef,
Videowindow_Release,
Videowindow_GetTypeInfoCount,
Videowindow_GetTypeInfo,
Videowindow_GetIDsOfNames,
Videowindow_Invoke,
Videowindow_put_Caption,
Videowindow_get_Caption,
Videowindow_put_WindowStyle,
Videowindow_get_WindowStyle,
Videowindow_put_WindowStyleEx,
Videowindow_get_WindowStyleEx,
Videowindow_put_AutoShow,
Videowindow_get_AutoShow,
Videowindow_put_WindowState,
Videowindow_get_WindowState,
Videowindow_put_BackgroundPalette,
Videowindow_get_BackgroundPalette,
Videowindow_put_Visible,
Videowindow_get_Visible,
Videowindow_put_Left,
Videowindow_get_Left,
Videowindow_put_Width,
Videowindow_get_Width,
Videowindow_put_Top,
Videowindow_get_Top,
Videowindow_put_Height,
Videowindow_get_Height,
Videowindow_put_Owner,
Videowindow_get_Owner,
Videowindow_put_MessageDrain,
Videowindow_get_MessageDrain,
Videowindow_get_BorderColor,
Videowindow_put_BorderColor,
Videowindow_get_FullScreenMode,
Videowindow_put_FullScreenMode,
Videowindow_SetWindowForeground,
Videowindow_NotifyOwnerMessage,
Videowindow_SetWindowPosition,
Videowindow_GetWindowPosition,
Videowindow_GetMinIdealImageSize,
Videowindow_GetMaxIdealImageSize,
Videowindow_GetRestorePosition,
Videowindow_HideCursor,
Videowindow_IsCursorHidden
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment