qcap: Implement the SmartTee allocator functions.

This commit is contained in:
Damjan Jovanovic 2015-05-31 20:10:30 +02:00 committed by Alexandre Julliard
parent 7c5f639cb8
commit 95c2b22c56
2 changed files with 51 additions and 22 deletions

View File

@ -374,12 +374,13 @@ static HRESULT WINAPI SmartTeeFilterCapture_GetMediaType(BasePin *base, int iPos
return S_FALSE;
}
static HRESULT WINAPI SmartTeeFilterCapture_DecideBufferSize(BaseOutputPin *base, IMemAllocator *alloc,
ALLOCATOR_PROPERTIES *ppropInputRequest)
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
{
SmartTeeFilter *This = impl_from_BasePin(&base->pin);
FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest);
return E_NOTIMPL;
TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
*pAlloc = This->input->pAllocator;
IMemAllocator_AddRef(This->input->pAllocator);
return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
}
static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base)
@ -396,8 +397,8 @@ static const BaseOutputPinFuncTable SmartTeeFilterCaptureFuncs = {
SmartTeeFilterCapture_GetMediaTypeVersion,
SmartTeeFilterCapture_GetMediaType
},
SmartTeeFilterCapture_DecideBufferSize,
BaseOutputPinImpl_DecideAllocator,
NULL,
SmartTeeFilterCapture_DecideAllocator,
SmartTeeFilterCapture_BreakConnect
};
@ -466,11 +467,13 @@ static HRESULT WINAPI SmartTeeFilterPreview_GetMediaType(BasePin *base, int iPos
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);
FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest);
return E_NOTIMPL;
TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
*pAlloc = This->input->pAllocator;
IMemAllocator_AddRef(This->input->pAllocator);
return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
}
static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base)
@ -487,8 +490,8 @@ static const BaseOutputPinFuncTable SmartTeeFilterPreviewFuncs = {
SmartTeeFilterPreview_GetMediaTypeVersion,
SmartTeeFilterPreview_GetMediaType
},
SmartTeeFilterPreview_DecideBufferSize,
BaseOutputPinImpl_DecideAllocator,
NULL,
SmartTeeFilterPreview_DecideAllocator,
SmartTeeFilterPreview_BreakConnect
};
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);
if (FAILED(hr))
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;
hr = BaseOutputPin_Construct(&SmartTeeFilterCaptureVtbl, sizeof(BaseOutputPin), &capturePinInfo,

View File

@ -41,6 +41,7 @@ typedef struct {
DWORD receiveThreadId;
IPin IPin_iface;
IMemInputPin IMemInputPin_iface;
IMemAllocator *allocator;
IBaseFilter *nullRenderer;
IPin *nullRendererPin;
IMemInputPin *nullRendererMemInputPin;
@ -106,6 +107,8 @@ static ULONG WINAPI SinkFilter_Release(IBaseFilter *iface)
SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface);
ULONG ref = InterlockedDecrement(&This->ref);
if(!ref) {
if (This->allocator)
IMemAllocator_Release(This->allocator);
IMemInputPin_Release(This->nullRendererMemInputPin);
IPin_Release(This->nullRendererPin);
IBaseFilter_Release(This->nullRenderer);
@ -493,6 +496,7 @@ static ULONG WINAPI SinkMemInputPin_Release(IMemInputPin *iface)
static HRESULT WINAPI SinkMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator)
{
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocator()\n");
return IMemInputPin_GetAllocator(This->nullRendererMemInputPin, ppAllocator);
}
@ -500,6 +504,9 @@ static HRESULT WINAPI SinkMemInputPin_NotifyAllocator(IMemInputPin *iface, IMemA
BOOL bReadOnly)
{
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);
}
@ -507,6 +514,7 @@ static HRESULT WINAPI SinkMemInputPin_GetAllocatorRequirements(IMemInputPin *ifa
ALLOCATOR_PROPERTIES *pProps)
{
SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface);
ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocatorRequirements()\n");
return IMemInputPin_GetAllocatorRequirements(This->nullRendererMemInputPin, pProps);
}
@ -727,7 +735,7 @@ static DWORD WINAPI media_thread(LPVOID param)
}
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);
}
@ -1016,7 +1024,7 @@ static HRESULT WINAPI SourcePin_Connect(IPin *iface, IPin *pReceivePin, const AM
hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (void**)&This->memInputPin);
if (SUCCEEDED(hr)) {
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)) {
ALLOCATOR_PROPERTIES requested, actual;
ZeroMemory(&requested, sizeof(ALLOCATOR_PROPERTIES));
@ -1272,6 +1280,7 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
SourceFilter *sourceFilter = NULL;
SinkFilter *captureSinkFilter = NULL;
SinkFilter *previewSinkFilter = NULL;
DWORD endTime;
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
(LPVOID*)&graphBuilder);
@ -1322,7 +1331,7 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
goto end;
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))
goto end;
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))
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);
ok(SUCCEEDED(hr), "couldn't get IMediaControl interface from IGraphBuilder, hr=0x%08x\n", hr);
if (FAILED(hr))
@ -1343,14 +1355,24 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in
if (FAILED(hr))
goto end;
while (previewSinkFilter->receiveThreadId == 0 || captureSinkFilter->receiveThreadId == 0)
WaitForSingleObject(event, INFINITE);
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");
endTime = GetTickCount() + 5000;
while (previewSinkFilter->receiveThreadId == 0 || captureSinkFilter->receiveThreadId == 0) {
DWORD now = GetTickCount();
if (now < endTime)
WaitForSingleObject(event, endTime - now);
else
break;
}
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);