qcap: Implement the SmartTee allocator functions.
This commit is contained in:
parent
7c5f639cb8
commit
95c2b22c56
|
@ -374,12 +374,13 @@ static HRESULT WINAPI SmartTeeFilterCapture_GetMediaType(BasePin *base, int iPos
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SmartTeeFilterCapture_DecideBufferSize(BaseOutputPin *base, IMemAllocator *alloc,
|
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
|
||||||
ALLOCATOR_PROPERTIES *ppropInputRequest)
|
|
||||||
{
|
{
|
||||||
SmartTeeFilter *This = impl_from_BasePin(&base->pin);
|
SmartTeeFilter *This = impl_from_BasePin(&base->pin);
|
||||||
FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest);
|
TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
|
||||||
return E_NOTIMPL;
|
*pAlloc = This->input->pAllocator;
|
||||||
|
IMemAllocator_AddRef(This->input->pAllocator);
|
||||||
|
return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base)
|
static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base)
|
||||||
|
@ -396,8 +397,8 @@ static const BaseOutputPinFuncTable SmartTeeFilterCaptureFuncs = {
|
||||||
SmartTeeFilterCapture_GetMediaTypeVersion,
|
SmartTeeFilterCapture_GetMediaTypeVersion,
|
||||||
SmartTeeFilterCapture_GetMediaType
|
SmartTeeFilterCapture_GetMediaType
|
||||||
},
|
},
|
||||||
SmartTeeFilterCapture_DecideBufferSize,
|
NULL,
|
||||||
BaseOutputPinImpl_DecideAllocator,
|
SmartTeeFilterCapture_DecideAllocator,
|
||||||
SmartTeeFilterCapture_BreakConnect
|
SmartTeeFilterCapture_BreakConnect
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -466,11 +467,13 @@ static HRESULT WINAPI SmartTeeFilterPreview_GetMediaType(BasePin *base, int iPos
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SmartTeeFilterPreview_DecideBufferSize(BaseOutputPin *base, IMemAllocator *alloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
|
static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
|
||||||
{
|
{
|
||||||
SmartTeeFilter *This = impl_from_BasePin(&base->pin);
|
SmartTeeFilter *This = impl_from_BasePin(&base->pin);
|
||||||
FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest);
|
TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
|
||||||
return E_NOTIMPL;
|
*pAlloc = This->input->pAllocator;
|
||||||
|
IMemAllocator_AddRef(This->input->pAllocator);
|
||||||
|
return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base)
|
static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base)
|
||||||
|
@ -487,8 +490,8 @@ static const BaseOutputPinFuncTable SmartTeeFilterPreviewFuncs = {
|
||||||
SmartTeeFilterPreview_GetMediaTypeVersion,
|
SmartTeeFilterPreview_GetMediaTypeVersion,
|
||||||
SmartTeeFilterPreview_GetMediaType
|
SmartTeeFilterPreview_GetMediaType
|
||||||
},
|
},
|
||||||
SmartTeeFilterPreview_DecideBufferSize,
|
NULL,
|
||||||
BaseOutputPinImpl_DecideAllocator,
|
SmartTeeFilterPreview_DecideAllocator,
|
||||||
SmartTeeFilterPreview_BreakConnect
|
SmartTeeFilterPreview_BreakConnect
|
||||||
};
|
};
|
||||||
IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
|
IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
|
||||||
|
@ -521,6 +524,10 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
|
||||||
&SmartTeeFilterInputFuncs, &This->filter.csFilter, NULL, (IPin**)&This->input);
|
&SmartTeeFilterInputFuncs, &This->filter.csFilter, NULL, (IPin**)&This->input);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto end;
|
goto end;
|
||||||
|
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IMemAllocator, (void**)&This->input->pAllocator);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto end;
|
||||||
|
|
||||||
capturePinInfo.pFilter = &This->filter.IBaseFilter_iface;
|
capturePinInfo.pFilter = &This->filter.IBaseFilter_iface;
|
||||||
hr = BaseOutputPin_Construct(&SmartTeeFilterCaptureVtbl, sizeof(BaseOutputPin), &capturePinInfo,
|
hr = BaseOutputPin_Construct(&SmartTeeFilterCaptureVtbl, sizeof(BaseOutputPin), &capturePinInfo,
|
||||||
|
|
|
@ -41,6 +41,7 @@ typedef struct {
|
||||||
DWORD receiveThreadId;
|
DWORD receiveThreadId;
|
||||||
IPin IPin_iface;
|
IPin IPin_iface;
|
||||||
IMemInputPin IMemInputPin_iface;
|
IMemInputPin IMemInputPin_iface;
|
||||||
|
IMemAllocator *allocator;
|
||||||
IBaseFilter *nullRenderer;
|
IBaseFilter *nullRenderer;
|
||||||
IPin *nullRendererPin;
|
IPin *nullRendererPin;
|
||||||
IMemInputPin *nullRendererMemInputPin;
|
IMemInputPin *nullRendererMemInputPin;
|
||||||
|
@ -106,6 +107,8 @@ static ULONG WINAPI SinkFilter_Release(IBaseFilter *iface)
|
||||||
SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface);
|
SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
if(!ref) {
|
if(!ref) {
|
||||||
|
if (This->allocator)
|
||||||
|
IMemAllocator_Release(This->allocator);
|
||||||
IMemInputPin_Release(This->nullRendererMemInputPin);
|
IMemInputPin_Release(This->nullRendererMemInputPin);
|
||||||
IPin_Release(This->nullRendererPin);
|
IPin_Release(This->nullRendererPin);
|
||||||
IBaseFilter_Release(This->nullRenderer);
|
IBaseFilter_Release(This->nullRenderer);
|
||||||
|
@ -493,6 +496,7 @@ static ULONG WINAPI SinkMemInputPin_Release(IMemInputPin *iface)
|
||||||
static HRESULT WINAPI SinkMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator)
|
static HRESULT WINAPI SinkMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator)
|
||||||
{
|
{
|
||||||
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
||||||
|
ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocator()\n");
|
||||||
return IMemInputPin_GetAllocator(This->nullRendererMemInputPin, ppAllocator);
|
return IMemInputPin_GetAllocator(This->nullRendererMemInputPin, ppAllocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,6 +504,9 @@ static HRESULT WINAPI SinkMemInputPin_NotifyAllocator(IMemInputPin *iface, IMemA
|
||||||
BOOL bReadOnly)
|
BOOL bReadOnly)
|
||||||
{
|
{
|
||||||
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
||||||
|
This->allocator = pAllocator;
|
||||||
|
IMemAllocator_AddRef(This->allocator);
|
||||||
|
ok(bReadOnly, "bReadOnly isn't supposed to be FALSE\n");
|
||||||
return IMemInputPin_NotifyAllocator(This->nullRendererMemInputPin, pAllocator, bReadOnly);
|
return IMemInputPin_NotifyAllocator(This->nullRendererMemInputPin, pAllocator, bReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +514,7 @@ static HRESULT WINAPI SinkMemInputPin_GetAllocatorRequirements(IMemInputPin *ifa
|
||||||
ALLOCATOR_PROPERTIES *pProps)
|
ALLOCATOR_PROPERTIES *pProps)
|
||||||
{
|
{
|
||||||
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
|
||||||
|
ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocatorRequirements()\n");
|
||||||
return IMemInputPin_GetAllocatorRequirements(This->nullRendererMemInputPin, pProps);
|
return IMemInputPin_GetAllocatorRequirements(This->nullRendererMemInputPin, pProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,7 +735,7 @@ static DWORD WINAPI media_thread(LPVOID param)
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IMemInputPin_Receive(This->memInputPin, sample);
|
hr = IMemInputPin_Receive(This->memInputPin, sample);
|
||||||
ok(SUCCEEDED(hr), "delivering sample to SmartTeeFilter's Input pin failed, hr=0x%08x\n", hr);
|
todo_wine ok(SUCCEEDED(hr), "delivering sample to SmartTeeFilter's Input pin failed, hr=0x%08x\n", hr);
|
||||||
|
|
||||||
IMediaSample_Release(sample);
|
IMediaSample_Release(sample);
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1024,7 @@ static HRESULT WINAPI SourcePin_Connect(IPin *iface, IPin *pReceivePin, const AM
|
||||||
hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (void**)&This->memInputPin);
|
hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (void**)&This->memInputPin);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = IMemInputPin_GetAllocator(This->memInputPin, &This->allocator);
|
hr = IMemInputPin_GetAllocator(This->memInputPin, &This->allocator);
|
||||||
todo_wine ok(SUCCEEDED(hr), "couldn't get allocator from SmartTeeFilter, hr=0x%08x\n", hr);
|
ok(SUCCEEDED(hr), "couldn't get allocator from SmartTeeFilter, hr=0x%08x\n", hr);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
ALLOCATOR_PROPERTIES requested, actual;
|
ALLOCATOR_PROPERTIES requested, actual;
|
||||||
ZeroMemory(&requested, sizeof(ALLOCATOR_PROPERTIES));
|
ZeroMemory(&requested, sizeof(ALLOCATOR_PROPERTIES));
|
||||||
|
@ -1272,6 +1280,7 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
|
||||||
SourceFilter *sourceFilter = NULL;
|
SourceFilter *sourceFilter = NULL;
|
||||||
SinkFilter *captureSinkFilter = NULL;
|
SinkFilter *captureSinkFilter = NULL;
|
||||||
SinkFilter *previewSinkFilter = NULL;
|
SinkFilter *previewSinkFilter = NULL;
|
||||||
|
DWORD endTime;
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
|
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
|
||||||
(LPVOID*)&graphBuilder);
|
(LPVOID*)&graphBuilder);
|
||||||
|
@ -1322,7 +1331,7 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
hr = IGraphBuilder_Connect(graphBuilder, &sourceFilter->IPin_iface, inputPin);
|
hr = IGraphBuilder_Connect(graphBuilder, &sourceFilter->IPin_iface, inputPin);
|
||||||
todo_wine ok(SUCCEEDED(hr), "couldn't connect source filter to Input pin, hr=0x%08x\n", hr);
|
ok(SUCCEEDED(hr), "couldn't connect source filter to Input pin, hr=0x%08x\n", hr);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto end;
|
goto end;
|
||||||
hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface);
|
hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface);
|
||||||
|
@ -1334,6 +1343,9 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
ok(sourceFilter->allocator == captureSinkFilter->allocator, "input and capture allocators don't match\n");
|
||||||
|
ok(sourceFilter->allocator == previewSinkFilter->allocator, "input and preview allocators don't match\n");
|
||||||
|
|
||||||
hr = IGraphBuilder_QueryInterface(graphBuilder, &IID_IMediaControl, (void**)&mediaControl);
|
hr = IGraphBuilder_QueryInterface(graphBuilder, &IID_IMediaControl, (void**)&mediaControl);
|
||||||
ok(SUCCEEDED(hr), "couldn't get IMediaControl interface from IGraphBuilder, hr=0x%08x\n", hr);
|
ok(SUCCEEDED(hr), "couldn't get IMediaControl interface from IGraphBuilder, hr=0x%08x\n", hr);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -1343,14 +1355,24 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
while (previewSinkFilter->receiveThreadId == 0 || captureSinkFilter->receiveThreadId == 0)
|
endTime = GetTickCount() + 5000;
|
||||||
WaitForSingleObject(event, INFINITE);
|
while (previewSinkFilter->receiveThreadId == 0 || captureSinkFilter->receiveThreadId == 0) {
|
||||||
ok(sourceFilter->mediaThreadId != captureSinkFilter->receiveThreadId,
|
DWORD now = GetTickCount();
|
||||||
"sending thread should != capture receiving thread\n");
|
if (now < endTime)
|
||||||
ok(sourceFilter->mediaThreadId != previewSinkFilter->receiveThreadId,
|
WaitForSingleObject(event, endTime - now);
|
||||||
"sending thread should != preview receiving thread\n");
|
else
|
||||||
ok(captureSinkFilter->receiveThreadId != previewSinkFilter->receiveThreadId,
|
break;
|
||||||
"capture receiving thread should != preview receiving thread");
|
}
|
||||||
|
if (previewSinkFilter->receiveThreadId != 0 && captureSinkFilter->receiveThreadId != 0) {
|
||||||
|
ok(sourceFilter->mediaThreadId != captureSinkFilter->receiveThreadId,
|
||||||
|
"sending thread should != capture receiving thread\n");
|
||||||
|
ok(sourceFilter->mediaThreadId != previewSinkFilter->receiveThreadId,
|
||||||
|
"sending thread should != preview receiving thread\n");
|
||||||
|
ok(captureSinkFilter->receiveThreadId != previewSinkFilter->receiveThreadId,
|
||||||
|
"capture receiving thread should != preview receiving thread");
|
||||||
|
} else {
|
||||||
|
todo_wine ok(0, "timeout: threads did not receive sample in time\n");
|
||||||
|
}
|
||||||
|
|
||||||
IMediaControl_Stop(mediaControl);
|
IMediaControl_Stop(mediaControl);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue