| /* |
| * Implementation of IMediaPosition for FilterGraph. |
| * |
| * FIXME - stub. |
| * |
| * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp> |
| * |
| * 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 |
| IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); |
| } |
| |
| static ULONG WINAPI |
| IMediaPosition_fnAddRef(IMediaPosition* iface) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_AddRef(This->unk.punkControl); |
| } |
| |
| static ULONG WINAPI |
| IMediaPosition_fnRelease(IMediaPosition* iface) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_Release(This->unk.punkControl); |
| } |
| |
| static HRESULT WINAPI |
| IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IDispatch_GetTypeInfoCount( |
| CFilterGraph_IDispatch(This),pcTypeInfo); |
| } |
| |
| static HRESULT WINAPI |
| IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IDispatch_GetTypeInfo( |
| CFilterGraph_IDispatch(This),iTypeInfo,lcid,ppobj); |
| } |
| |
| static HRESULT WINAPI |
| IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IDispatch_GetIDsOfNames( |
| CFilterGraph_IDispatch(This),riid,ppwszName,cNames,lcid,pDispId); |
| } |
| |
| static HRESULT WINAPI |
| IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IDispatch_Invoke( |
| CFilterGraph_IDispatch(This), |
| DispId,riid,lcid,wFlags,pDispParams,pVarRes,pExcepInfo,puArgErr); |
| } |
| |
| |
| static HRESULT WINAPI |
| IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| HRESULT hr = E_NOTIMPL; |
| HRESULT hrFilter; |
| DWORD n; |
| |
| TRACE("(%p)->(%p)\n",This,prefTime); |
| |
| EnterCriticalSection( &This->m_csFilters ); |
| |
| for ( n = 0; n < This->m_cActiveFilters; n++ ) |
| { |
| if ( This->m_pActiveFilters[n].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_get_Duration( This->m_pActiveFilters[n].pPosition, prefTime ); |
| 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 |
| IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_put_CurrentPosition( This->m_pActiveFilters[n].pPosition, refTime ); |
| 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 |
| IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_get_CurrentPosition( This->m_pActiveFilters[n].pPosition, prefTime ); |
| 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 |
| IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_get_StopTime( This->m_pActiveFilters[n].pPosition, prefTime ); |
| 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 |
| IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_put_StopTime( This->m_pActiveFilters[n].pPosition, refTime ); |
| 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 |
| IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_get_PrerollTime( This->m_pActiveFilters[n].pPosition, prefTime ); |
| 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 |
| IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_put_PrerollTime( This->m_pActiveFilters[n].pPosition, refTime ); |
| 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 |
| IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_put_Rate( This->m_pActiveFilters[n].pPosition, 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 |
| IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_get_Rate( This->m_pActiveFilters[n].pPosition, 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 |
| IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_CanSeekForward( This->m_pActiveFilters[n].pPosition, pCanSeek ); |
| 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 |
| IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek) |
| { |
| CFilterGraph_THIS(iface,mediaposition); |
| 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].pPosition != NULL ) |
| { |
| hrFilter = IMediaPosition_CanSeekBackward( This->m_pActiveFilters[n].pPosition, pCanSeek ); |
| 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(IMediaPosition) imediaposition = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| /* IUnknown fields */ |
| IMediaPosition_fnQueryInterface, |
| IMediaPosition_fnAddRef, |
| IMediaPosition_fnRelease, |
| /* IDispatch fields */ |
| IMediaPosition_fnGetTypeInfoCount, |
| IMediaPosition_fnGetTypeInfo, |
| IMediaPosition_fnGetIDsOfNames, |
| IMediaPosition_fnInvoke, |
| /* IMediaPosition fields */ |
| IMediaPosition_fnget_Duration, |
| IMediaPosition_fnput_CurrentPosition, |
| IMediaPosition_fnget_CurrentPosition, |
| IMediaPosition_fnget_StopTime, |
| IMediaPosition_fnput_StopTime, |
| IMediaPosition_fnget_PrerollTime, |
| IMediaPosition_fnput_PrerollTime, |
| IMediaPosition_fnput_Rate, |
| IMediaPosition_fnget_Rate, |
| IMediaPosition_fnCanSeekForward, |
| IMediaPosition_fnCanSeekBackward, |
| }; |
| |
| |
| HRESULT CFilterGraph_InitIMediaPosition( CFilterGraph* pfg ) |
| { |
| TRACE("(%p)\n",pfg); |
| ICOM_VTBL(&pfg->mediaposition) = &imediaposition; |
| |
| return NOERROR; |
| } |
| |
| void CFilterGraph_UninitIMediaPosition( CFilterGraph* pfg ) |
| { |
| TRACE("(%p)\n",pfg); |
| } |