Damjan Jovanovic : qcap: Implement the SmartTee allocator functions.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jun 2 07:50:05 CDT 2015
Module: wine
Branch: master
Commit: 95c2b22c569757e0fccfc87967511fb3ea9b780a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=95c2b22c569757e0fccfc87967511fb3ea9b780a
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Sun May 31 20:10:30 2015 +0200
qcap: Implement the SmartTee allocator functions.
---
dlls/qcap/smartteefilter.c | 29 ++++++++++++++++----------
dlls/qcap/tests/smartteefilter.c | 44 ++++++++++++++++++++++++++++++----------
2 files changed, 51 insertions(+), 22 deletions(-)
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 9af2e9a..d550169 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -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,
diff --git a/dlls/qcap/tests/smartteefilter.c b/dlls/qcap/tests/smartteefilter.c
index 1255887..e23e66f 100644
--- a/dlls/qcap/tests/smartteefilter.c
+++ b/dlls/qcap/tests/smartteefilter.c
@@ -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);
More information about the wine-cvs
mailing list