Maarten Lankhorst : quartz: Implement a few MediaSeeking functions.
Alexandre Julliard
julliard at winehq.org
Sat Mar 15 05:53:51 CDT 2008
Module: wine
Branch: master
Commit: 0f8b16f117207a1f9e41963cb732cca44b492ab3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0f8b16f117207a1f9e41963cb732cca44b492ab3
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Fri Mar 14 16:22:55 2008 -0700
quartz: Implement a few MediaSeeking functions.
---
dlls/quartz/filtergraph.c | 132 +++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 127 insertions(+), 5 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 2da1166..887c682 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1695,22 +1695,119 @@ static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) {
return Filtergraph_Release(This);
}
+typedef HRESULT WINAPI (*fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DWORD_PTR arg);
+
+static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) {
+ BOOL allnotimpl = TRUE;
+ int i;
+ IBaseFilter* pfilter;
+ IEnumPins* pEnum;
+ HRESULT hr, hr_return = S_OK;
+ IPin* pPin;
+ DWORD dummy;
+ PIN_DIRECTION dir;
+
+ TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg);
+ /* Send a message to all renderers, they are responsible for broadcasting it further */
+
+ for(i = 0; i < This->nFilters; i++)
+ {
+ BOOL renderer = TRUE;
+ pfilter = This->ppFiltersInGraph[i];
+ hr = IBaseFilter_EnumPins(pfilter, &pEnum);
+ if (hr != S_OK)
+ {
+ ERR("Enum pins failed %x\n", hr);
+ continue;
+ }
+ /* Check if it is a source filter */
+ while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
+ {
+ IPin_QueryDirection(pPin, &dir);
+ IPin_Release(pPin);
+ if (dir != PINDIR_INPUT)
+ {
+ renderer = FALSE;
+ break;
+ }
+ }
+ IEnumPins_Release(pEnum);
+ if (renderer)
+ {
+ IMediaSeeking *seek = NULL;
+ IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek);
+ if (!seek)
+ continue;
+ hr = FoundSeek(This, seek, arg);
+ IMediaSeeking_Release(seek);
+ if (hr_return != E_NOTIMPL)
+ allnotimpl = FALSE;
+ if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && !FAILED(hr_return)))
+ hr_return = hr;
+ }
+ }
+
+ if (allnotimpl)
+ return E_NOTIMPL;
+ return hr_return;
+}
+
+static HRESULT WINAPI FoundCapabilities(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pcaps)
+{
+ HRESULT hr;
+ DWORD caps = 0;
+
+ hr = IMediaSeeking_GetCapabilities(seek, &caps);
+ if (FAILED(hr))
+ return hr;
+
+ /* Only add common capabilities everything supports */
+ *(DWORD*)pcaps &= caps;
+
+ return hr;
+}
+
/*** IMediaSeeking methods ***/
static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface,
DWORD *pCapabilities) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
+ HRESULT hr;
+ TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
- FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
+ if (!pCapabilities)
+ return E_POINTER;
- return S_OK;
+ EnterCriticalSection(&This->cs);
+ *pCapabilities = 0xffffffff;
+
+ hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
+ LeaveCriticalSection(&This->cs);
+
+ return hr;
}
static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface,
DWORD *pCapabilities) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
+ DWORD originalcaps;
+ HRESULT hr;
+ TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities);
+
+ if (!pCapabilities)
+ return E_POINTER;
- FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pCapabilities);
+ EnterCriticalSection(&This->cs);
+ originalcaps = *pCapabilities;
+ hr = all_renderers_seek(This, FoundCapabilities, (DWORD_PTR)pCapabilities);
+ LeaveCriticalSection(&This->cs);
+
+ if (FAILED(hr))
+ return hr;
+ if (!*pCapabilities)
+ return E_FAIL;
+ if (*pCapabilities != originalcaps)
+ return S_FALSE;
return S_OK;
}
@@ -1793,13 +1890,38 @@ static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface,
return S_OK;
}
+static HRESULT WINAPI FoundDuration(IFilterGraphImpl *This, IMediaSeeking *seek, DWORD_PTR pduration)
+{
+ HRESULT hr;
+ LONGLONG duration = 0, *pdur = (LONGLONG*)pduration;
+
+ hr = IMediaSeeking_GetDuration(seek, &duration);
+ if (FAILED(hr))
+ return hr;
+
+ /* FIXME: Minimum or maximum duration? */
+ if (!*pdur < duration)
+ *pdur = duration;
+
+ return hr;
+}
+
static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface,
LONGLONG *pDuration) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
+ HRESULT hr;
- FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pDuration);
+ TRACE("(%p/%p)->(%p)\n", This, iface, pDuration);
- return S_OK;
+ if (!pDuration)
+ return E_POINTER;
+
+ EnterCriticalSection(&This->cs);
+ *pDuration = 0;
+ hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration);
+ LeaveCriticalSection(&This->cs);
+
+ return hr;
}
static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
More information about the wine-cvs
mailing list