/* * Implementation of IMediaSeeking for FilterGraph. * * FIXME - stub. * FIXME - this interface should be allocated as a plug-in(?) * * Copyright (C) Hidenori TAKESHIMA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "windef.h" #include "winbase.h" #include "wingdi.h" #include "winuser.h" #include "winerror.h" #include "strmif.h" #include "control.h" #include "uuids.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "fgraph.h" static HRESULT WINAPI IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj) { CFilterGraph_THIS(iface,mediaseeking); TRACE("(%p)->()\n",This); return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); } static ULONG WINAPI IMediaSeeking_fnAddRef(IMediaSeeking* iface) { CFilterGraph_THIS(iface,mediaseeking); TRACE("(%p)->()\n",This); return IUnknown_AddRef(This->unk.punkControl); } static ULONG WINAPI IMediaSeeking_fnRelease(IMediaSeeking* iface) { CFilterGraph_THIS(iface,mediaseeking); TRACE("(%p)->()\n",This); return IUnknown_Release(This->unk.punkControl); } static HRESULT WINAPI IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetCapabilities( This->m_pActiveFilters[n].pSeeking, pdwCaps ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_CheckCapabilities( This->m_pActiveFilters[n].pSeeking, pdwCaps ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_IsFormatSupported( This->m_pActiveFilters[n].pSeeking, pidFormat ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_QueryPreferredFormat( This->m_pActiveFilters[n].pSeeking, pidFormat ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_IsUsingTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_SetTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetDuration( This->m_pActiveFilters[n].pSeeking, pllDuration ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetStopPosition( This->m_pActiveFilters[n].pSeeking, pllPos ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetCurrentPosition( This->m_pActiveFilters[n].pSeeking, pllPos ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_ConvertTimeFormat( This->m_pActiveFilters[n].pSeeking, pllOut, pidFmtOut, llIn, pidFmtIn ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_SetPositions( This->m_pActiveFilters[n].pSeeking, pllCur, dwCurFlags, pllStop, dwStopFlags ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetPositions( This->m_pActiveFilters[n].pSeeking, pllCur, pllStop ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetAvailable( This->m_pActiveFilters[n].pSeeking, pllFirst, pllLast ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_SetRate( This->m_pActiveFilters[n].pSeeking, dblRate ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetRate( This->m_pActiveFilters[n].pSeeking, pdblRate ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static HRESULT WINAPI IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll) { CFilterGraph_THIS(iface,mediaseeking); HRESULT hr = E_NOTIMPL; HRESULT hrFilter; DWORD n; TRACE("(%p)->()\n",This); EnterCriticalSection( &This->m_csFilters ); for ( n = 0; n < This->m_cActiveFilters; n++ ) { if ( This->m_pActiveFilters[n].pSeeking != NULL ) { hrFilter = IMediaSeeking_GetPreroll( This->m_pActiveFilters[n].pSeeking, pllPreroll ); if ( hr == E_NOTIMPL ) { hr = hrFilter; } else if ( hrFilter != E_NOTIMPL ) { if ( SUCCEEDED(hr) ) hr = hrFilter; } } } LeaveCriticalSection( &This->m_csFilters ); return hr; } static ICOM_VTABLE(IMediaSeeking) imediaseeking = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE /* IUnknown fields */ IMediaSeeking_fnQueryInterface, IMediaSeeking_fnAddRef, IMediaSeeking_fnRelease, /* IMediaSeeking fields */ IMediaSeeking_fnGetCapabilities, IMediaSeeking_fnCheckCapabilities, IMediaSeeking_fnIsFormatSupported, IMediaSeeking_fnQueryPreferredFormat, IMediaSeeking_fnGetTimeFormat, IMediaSeeking_fnIsUsingTimeFormat, IMediaSeeking_fnSetTimeFormat, IMediaSeeking_fnGetDuration, IMediaSeeking_fnGetStopPosition, IMediaSeeking_fnGetCurrentPosition, IMediaSeeking_fnConvertTimeFormat, IMediaSeeking_fnSetPositions, IMediaSeeking_fnGetPositions, IMediaSeeking_fnGetAvailable, IMediaSeeking_fnSetRate, IMediaSeeking_fnGetRate, IMediaSeeking_fnGetPreroll, }; HRESULT CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->mediaseeking) = &imediaseeking; return NOERROR; } void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); }