quartz: Update null renderer to use the BaseRenderer from strmbase.
This commit is contained in:
parent
fa3838e9de
commit
3b85b13e27
|
@ -41,88 +41,53 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
|
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
|
||||||
|
|
||||||
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
|
|
||||||
static const WCHAR wcsAltInputPinName[] = {'I','n',0};
|
|
||||||
|
|
||||||
static const IBaseFilterVtbl NullRenderer_Vtbl;
|
static const IBaseFilterVtbl NullRenderer_Vtbl;
|
||||||
static const IUnknownVtbl IInner_VTable;
|
static const IUnknownVtbl IInner_VTable;
|
||||||
static const IPinVtbl NullRenderer_InputPin_Vtbl;
|
|
||||||
static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl;
|
static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl;
|
||||||
|
|
||||||
typedef struct NullRendererImpl
|
typedef struct NullRendererImpl
|
||||||
{
|
{
|
||||||
BaseFilter filter;
|
BaseRenderer renderer;
|
||||||
|
|
||||||
const IUnknownVtbl * IInner_vtbl;
|
const IUnknownVtbl * IInner_vtbl;
|
||||||
const IAMFilterMiscFlagsVtbl *IAMFilterMiscFlags_vtbl;
|
const IAMFilterMiscFlagsVtbl *IAMFilterMiscFlags_vtbl;
|
||||||
IUnknown *seekthru_unk;
|
|
||||||
|
|
||||||
BaseInputPin *pInputPin;
|
|
||||||
IUnknown * pUnkOuter;
|
IUnknown * pUnkOuter;
|
||||||
BOOL bUnkOuterValid;
|
BOOL bUnkOuterValid;
|
||||||
BOOL bAggregatable;
|
BOOL bAggregatable;
|
||||||
} NullRendererImpl;
|
} NullRendererImpl;
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_Receive(BaseInputPin *pin, IMediaSample * pSample)
|
static HRESULT WINAPI NullRenderer_DoRenderSample(BaseRenderer *iface, IMediaSample *pMediaSample)
|
||||||
{
|
{
|
||||||
NullRendererImpl *This = ((NullRendererImpl*)pin->pin.pinInfo.pFilter);
|
return S_OK;
|
||||||
HRESULT hr = S_OK;
|
|
||||||
REFERENCE_TIME start, stop;
|
|
||||||
|
|
||||||
TRACE("%p %p\n", pin, pSample);
|
|
||||||
|
|
||||||
if (SUCCEEDED(IMediaSample_GetMediaTime(pSample, &start, &stop)))
|
|
||||||
RendererPosPassThru_RegisterMediaTime(This->seekthru_unk, start);
|
|
||||||
EnterCriticalSection(&This->filter.csFilter);
|
|
||||||
if (This->pInputPin->flushing || This->pInputPin->end_of_stream)
|
|
||||||
hr = S_FALSE;
|
|
||||||
LeaveCriticalSection(&This->filter.csFilter);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_CheckMediaType(BasePin *iface, const AM_MEDIA_TYPE * pmt)
|
static HRESULT WINAPI NullRenderer_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
|
||||||
{
|
{
|
||||||
TRACE("Not a stub!\n");
|
TRACE("Not a stub!\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPin* WINAPI NullRenderer_GetPin(BaseFilter *iface, int pos)
|
static const BaseRendererFuncTable RendererFuncTable = {
|
||||||
{
|
|
||||||
NullRendererImpl *This = (NullRendererImpl *)iface;
|
|
||||||
|
|
||||||
if (pos >= 1 || pos < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
IPin_AddRef((IPin *)This->pInputPin);
|
|
||||||
return (IPin *)This->pInputPin;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LONG WINAPI NullRenderer_GetPinCount(BaseFilter *iface)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const BaseFilterFuncTable BaseFuncTable = {
|
|
||||||
NullRenderer_GetPin,
|
|
||||||
NullRenderer_GetPinCount
|
|
||||||
};
|
|
||||||
|
|
||||||
static const BasePinFuncTable input_BaseFuncTable = {
|
|
||||||
NullRenderer_CheckMediaType,
|
NullRenderer_CheckMediaType,
|
||||||
|
NullRenderer_DoRenderSample,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
BasePinImpl_GetMediaTypeVersion,
|
|
||||||
BasePinImpl_GetMediaType
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const BaseInputPinFuncTable input_BaseInputFuncTable = {
|
|
||||||
NullRenderer_Receive
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
PIN_INFO piInput;
|
|
||||||
NullRendererImpl * pNullRenderer;
|
NullRendererImpl * pNullRenderer;
|
||||||
|
|
||||||
TRACE("(%p, %p)\n", pUnkOuter, ppv);
|
TRACE("(%p, %p)\n", pUnkOuter, ppv);
|
||||||
|
@ -136,29 +101,15 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
pNullRenderer->IInner_vtbl = &IInner_VTable;
|
pNullRenderer->IInner_vtbl = &IInner_VTable;
|
||||||
pNullRenderer->IAMFilterMiscFlags_vtbl = &IAMFilterMiscFlags_Vtbl;
|
pNullRenderer->IAMFilterMiscFlags_vtbl = &IAMFilterMiscFlags_Vtbl;
|
||||||
|
|
||||||
BaseFilter_Init(&pNullRenderer->filter, &NullRenderer_Vtbl, &CLSID_NullRenderer, (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"), &BaseFuncTable);
|
hr = BaseRenderer_Init(&pNullRenderer->renderer, &NullRenderer_Vtbl, pUnkOuter, &CLSID_NullRenderer, (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"), &RendererFuncTable);
|
||||||
|
|
||||||
/* construct input pin */
|
if (FAILED(hr))
|
||||||
piInput.dir = PINDIR_INPUT;
|
|
||||||
piInput.pFilter = (IBaseFilter *)pNullRenderer;
|
|
||||||
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
|
||||||
|
|
||||||
hr = BaseInputPin_Construct(&NullRenderer_InputPin_Vtbl, &piInput, &input_BaseFuncTable, &input_BaseInputFuncTable, &pNullRenderer->filter.csFilter, NULL, (IPin **)&pNullRenderer->pInputPin);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
{
|
||||||
hr = CreatePosPassThru(pUnkOuter ? pUnkOuter : (IUnknown*)&pNullRenderer->IInner_vtbl, TRUE, (IPin*)pNullRenderer->pInputPin, &pNullRenderer->seekthru_unk);
|
BaseRendererImpl_Release(&pNullRenderer->renderer.filter.IBaseFilter_iface);
|
||||||
if (FAILED(hr)) {
|
|
||||||
IUnknown_Release((IUnknown*)pNullRenderer);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
*ppv = pNullRenderer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BaseFilterImpl_Release((IBaseFilter*)pNullRenderer);
|
|
||||||
CoTaskMemFree(pNullRenderer);
|
CoTaskMemFree(pNullRenderer);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*ppv = pNullRenderer;
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -175,16 +126,15 @@ static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown * iface, REFIID
|
||||||
|
|
||||||
if (IsEqualIID(riid, &IID_IUnknown))
|
if (IsEqualIID(riid, &IID_IUnknown))
|
||||||
*ppv = &This->IInner_vtbl;
|
*ppv = &This->IInner_vtbl;
|
||||||
else if (IsEqualIID(riid, &IID_IPersist))
|
|
||||||
*ppv = This;
|
|
||||||
else if (IsEqualIID(riid, &IID_IMediaFilter))
|
|
||||||
*ppv = This;
|
|
||||||
else if (IsEqualIID(riid, &IID_IBaseFilter))
|
|
||||||
*ppv = This;
|
|
||||||
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
|
||||||
return IUnknown_QueryInterface(This->seekthru_unk, riid, ppv);
|
|
||||||
else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
|
else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
|
||||||
*ppv = &This->IAMFilterMiscFlags_vtbl;
|
*ppv = &This->IAMFilterMiscFlags_vtbl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
if (*ppv)
|
if (*ppv)
|
||||||
{
|
{
|
||||||
|
@ -201,38 +151,16 @@ static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown * iface, REFIID
|
||||||
static ULONG WINAPI NullRendererInner_AddRef(IUnknown * iface)
|
static ULONG WINAPI NullRendererInner_AddRef(IUnknown * iface)
|
||||||
{
|
{
|
||||||
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
|
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
|
||||||
ULONG refCount = InterlockedIncrement(&This->filter.refCount);
|
return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
|
||||||
|
|
||||||
TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
|
|
||||||
|
|
||||||
return refCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI NullRendererInner_Release(IUnknown * iface)
|
static ULONG WINAPI NullRendererInner_Release(IUnknown * iface)
|
||||||
{
|
{
|
||||||
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
|
ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface);
|
||||||
ULONG refCount = InterlockedDecrement(&This->filter.refCount);
|
ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
|
||||||
|
|
||||||
TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
|
|
||||||
|
|
||||||
if (!refCount)
|
if (!refCount)
|
||||||
{
|
{
|
||||||
IPin *pConnectedTo;
|
|
||||||
|
|
||||||
if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
|
|
||||||
{
|
|
||||||
IPin_Disconnect(pConnectedTo);
|
|
||||||
IPin_Release(pConnectedTo);
|
|
||||||
}
|
|
||||||
IPin_Disconnect((IPin *)This->pInputPin);
|
|
||||||
IPin_Release((IPin *)This->pInputPin);
|
|
||||||
|
|
||||||
if (This->seekthru_unk)
|
|
||||||
IUnknown_Release(This->seekthru_unk);
|
|
||||||
|
|
||||||
This->filter.csFilter.DebugInfo->Spare[0] = 0;
|
|
||||||
DeleteCriticalSection(&This->filter.csFilter);
|
|
||||||
|
|
||||||
TRACE("Destroying Null Renderer\n");
|
TRACE("Destroying Null Renderer\n");
|
||||||
CoTaskMemFree(This);
|
CoTaskMemFree(This);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -296,178 +224,25 @@ static ULONG WINAPI NullRenderer_Release(IBaseFilter * iface)
|
||||||
return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
|
return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** IMediaFilter methods **/
|
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_Stop(IBaseFilter * iface)
|
|
||||||
{
|
|
||||||
NullRendererImpl *This = (NullRendererImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->()\n", This, iface);
|
|
||||||
|
|
||||||
EnterCriticalSection(&This->filter.csFilter);
|
|
||||||
{
|
|
||||||
This->filter.state = State_Stopped;
|
|
||||||
RendererPosPassThru_ResetMediaTime(This->seekthru_unk);
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&This->filter.csFilter);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_Pause(IBaseFilter * iface)
|
|
||||||
{
|
|
||||||
NullRendererImpl *This = (NullRendererImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->()\n", This, iface);
|
|
||||||
|
|
||||||
EnterCriticalSection(&This->filter.csFilter);
|
|
||||||
{
|
|
||||||
if (This->filter.state == State_Stopped)
|
|
||||||
This->pInputPin->end_of_stream = 0;
|
|
||||||
This->filter.state = State_Paused;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&This->filter.csFilter);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
NullRendererImpl *This = (NullRendererImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
|
|
||||||
|
|
||||||
EnterCriticalSection(&This->filter.csFilter);
|
|
||||||
This->filter.rtStreamStart = tStart;
|
|
||||||
if (This->filter.state == State_Running)
|
|
||||||
goto out;
|
|
||||||
if (This->pInputPin->pin.pConnectedTo)
|
|
||||||
{
|
|
||||||
This->pInputPin->end_of_stream = 0;
|
|
||||||
}
|
|
||||||
else if (This->filter.filterInfo.pGraph)
|
|
||||||
{
|
|
||||||
IMediaEventSink *pEventSink;
|
|
||||||
hr = IFilterGraph_QueryInterface(This->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)This);
|
|
||||||
IMediaEventSink_Release(pEventSink);
|
|
||||||
}
|
|
||||||
hr = S_OK;
|
|
||||||
}
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
This->filter.state = State_Running;
|
|
||||||
out:
|
|
||||||
LeaveCriticalSection(&This->filter.csFilter);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** IBaseFilter implementation **/
|
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
|
|
||||||
{
|
|
||||||
NullRendererImpl *This = (NullRendererImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_w(Id), ppPin);
|
|
||||||
|
|
||||||
if (!Id || !ppPin)
|
|
||||||
return E_POINTER;
|
|
||||||
|
|
||||||
if (!lstrcmpiW(Id,wcsInputPinName) || !lstrcmpiW(Id,wcsAltInputPinName))
|
|
||||||
{
|
|
||||||
*ppPin = (IPin *)This->pInputPin;
|
|
||||||
IPin_AddRef(*ppPin);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
*ppPin = NULL;
|
|
||||||
return VFW_E_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const IBaseFilterVtbl NullRenderer_Vtbl =
|
static const IBaseFilterVtbl NullRenderer_Vtbl =
|
||||||
{
|
{
|
||||||
NullRenderer_QueryInterface,
|
NullRenderer_QueryInterface,
|
||||||
NullRenderer_AddRef,
|
NullRenderer_AddRef,
|
||||||
NullRenderer_Release,
|
NullRenderer_Release,
|
||||||
BaseFilterImpl_GetClassID,
|
BaseFilterImpl_GetClassID,
|
||||||
NullRenderer_Stop,
|
BaseRendererImpl_Stop,
|
||||||
NullRenderer_Pause,
|
BaseRendererImpl_Pause,
|
||||||
NullRenderer_Run,
|
BaseRendererImpl_Run,
|
||||||
BaseFilterImpl_GetState,
|
BaseFilterImpl_GetState,
|
||||||
BaseFilterImpl_SetSyncSource,
|
BaseFilterImpl_SetSyncSource,
|
||||||
BaseFilterImpl_GetSyncSource,
|
BaseFilterImpl_GetSyncSource,
|
||||||
BaseFilterImpl_EnumPins,
|
BaseFilterImpl_EnumPins,
|
||||||
NullRenderer_FindPin,
|
BaseRendererImpl_FindPin,
|
||||||
BaseFilterImpl_QueryFilterInfo,
|
BaseFilterImpl_QueryFilterInfo,
|
||||||
BaseFilterImpl_JoinFilterGraph,
|
BaseFilterImpl_JoinFilterGraph,
|
||||||
BaseFilterImpl_QueryVendorInfo
|
BaseFilterImpl_QueryVendorInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
|
|
||||||
{
|
|
||||||
BaseInputPin* This = (BaseInputPin*)iface;
|
|
||||||
IMediaEventSink* pEventSink;
|
|
||||||
NullRendererImpl *pNull;
|
|
||||||
IFilterGraph *graph;
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->()\n", This, iface);
|
|
||||||
|
|
||||||
BaseInputPinImpl_EndOfStream(iface);
|
|
||||||
pNull = (NullRendererImpl*)This->pin.pinInfo.pFilter;
|
|
||||||
graph = pNull->filter.filterInfo.pGraph;
|
|
||||||
if (graph)
|
|
||||||
{
|
|
||||||
hr = IFilterGraph_QueryInterface(pNull->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)pNull);
|
|
||||||
IMediaEventSink_Release(pEventSink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RendererPosPassThru_EOS(pNull->seekthru_unk);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI NullRenderer_InputPin_EndFlush(IPin * iface)
|
|
||||||
{
|
|
||||||
BaseInputPin* This = (BaseInputPin*)iface;
|
|
||||||
NullRendererImpl *pNull;
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->()\n", This, iface);
|
|
||||||
|
|
||||||
hr = BaseInputPinImpl_EndOfStream(iface);
|
|
||||||
pNull = (NullRendererImpl*)This->pin.pinInfo.pFilter;
|
|
||||||
RendererPosPassThru_ResetMediaTime(pNull->seekthru_unk);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const IPinVtbl NullRenderer_InputPin_Vtbl =
|
|
||||||
{
|
|
||||||
BaseInputPinImpl_QueryInterface,
|
|
||||||
BasePinImpl_AddRef,
|
|
||||||
BaseInputPinImpl_Release,
|
|
||||||
BaseInputPinImpl_Connect,
|
|
||||||
BaseInputPinImpl_ReceiveConnection,
|
|
||||||
BasePinImpl_Disconnect,
|
|
||||||
BasePinImpl_ConnectedTo,
|
|
||||||
BasePinImpl_ConnectionMediaType,
|
|
||||||
BasePinImpl_QueryPinInfo,
|
|
||||||
BasePinImpl_QueryDirection,
|
|
||||||
BasePinImpl_QueryId,
|
|
||||||
BaseInputPinImpl_QueryAccept,
|
|
||||||
BasePinImpl_EnumMediaTypes,
|
|
||||||
BasePinImpl_QueryInternalConnections,
|
|
||||||
NullRenderer_InputPin_EndOfStream,
|
|
||||||
BaseInputPinImpl_BeginFlush,
|
|
||||||
NullRenderer_InputPin_EndFlush,
|
|
||||||
BaseInputPinImpl_NewSegment
|
|
||||||
};
|
|
||||||
|
|
||||||
static NullRendererImpl *from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) {
|
static NullRendererImpl *from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) {
|
||||||
return (NullRendererImpl*)((char*)iface - offsetof(NullRendererImpl, IAMFilterMiscFlags_vtbl));
|
return (NullRendererImpl*)((char*)iface - offsetof(NullRendererImpl, IAMFilterMiscFlags_vtbl));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue