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