ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

control.c
Go to the documentation of this file.
00001 /*
00002  * Filter Seeking and Control Interfaces
00003  *
00004  * Copyright 2003 Robert Shearman
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 /* FIXME: critical sections */
00021 
00022 #include "quartz_private.h"
00023 #include "control_private.h"
00024 
00025 #include "uuids.h"
00026 #include "wine/debug.h"
00027 
00028 #include <assert.h>
00029 
00030 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
00031 
00032 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl;
00033 
00034 typedef struct PassThruImpl {
00035     const ISeekingPassThruVtbl *IPassThru_vtbl;
00036     const IUnknownVtbl *IInner_vtbl;
00037     const IMediaSeekingVtbl *IMediaSeeking_vtbl;
00038 
00039     LONG ref;
00040     IUnknown * pUnkOuter;
00041     IPin * pin;
00042     BOOL bUnkOuterValid;
00043     BOOL bAggregatable;
00044     BOOL renderer;
00045 } PassThruImpl;
00046 
00047 static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface,
00048                       REFIID riid,
00049                       LPVOID *ppvObj) {
00050     ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
00051     TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
00052 
00053     if (This->bAggregatable)
00054         This->bUnkOuterValid = TRUE;
00055 
00056     if (IsEqualGUID(&IID_IUnknown, riid))
00057     {
00058         *ppvObj = &(This->IInner_vtbl);
00059         TRACE("   returning IUnknown interface (%p)\n", *ppvObj);
00060     } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) {
00061         *ppvObj = &(This->IPassThru_vtbl);
00062         TRACE("   returning ISeekingPassThru interface (%p)\n", *ppvObj);
00063     } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
00064         *ppvObj = &(This->IMediaSeeking_vtbl);
00065         TRACE("   returning IMediaSeeking interface (%p)\n", *ppvObj);
00066     } else {
00067         *ppvObj = NULL;
00068         FIXME("unknown interface %s\n", debugstr_guid(riid));
00069         return E_NOINTERFACE;
00070     }
00071 
00072     IUnknown_AddRef((IUnknown *)(*ppvObj));
00073     return S_OK;
00074 }
00075 
00076 static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) {
00077     ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
00078     ULONG ref = InterlockedIncrement(&This->ref);
00079 
00080     TRACE("(%p)->(): new ref = %d\n", This, ref);
00081 
00082     return ref;
00083 }
00084 
00085 static ULONG WINAPI SeekInner_Release(IUnknown * iface) {
00086     ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface);
00087     ULONG ref = InterlockedDecrement(&This->ref);
00088 
00089     TRACE("(%p)->(): new ref = %d\n", This, ref);
00090 
00091     if (ref == 0)
00092     {
00093         CoTaskMemFree(This);
00094     }
00095     return ref;
00096 }
00097 
00098 static const IUnknownVtbl IInner_VTable =
00099 {
00100     SeekInner_QueryInterface,
00101     SeekInner_AddRef,
00102     SeekInner_Release
00103 };
00104 
00105 /* Generic functions for aggregation */
00106 static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv)
00107 {
00108     if (This->bAggregatable)
00109         This->bUnkOuterValid = TRUE;
00110 
00111     if (This->pUnkOuter)
00112     {
00113         if (This->bAggregatable)
00114             return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
00115 
00116         if (IsEqualIID(riid, &IID_IUnknown))
00117         {
00118             HRESULT hr;
00119 
00120             IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
00121             hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
00122             IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
00123             This->bAggregatable = TRUE;
00124             return hr;
00125         }
00126 
00127         *ppv = NULL;
00128         return E_NOINTERFACE;
00129     }
00130 
00131     return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
00132 }
00133 
00134 static ULONG SeekOuter_AddRef(PassThruImpl *This)
00135 {
00136     if (This->pUnkOuter && This->bUnkOuterValid)
00137         return IUnknown_AddRef(This->pUnkOuter);
00138     return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
00139 }
00140 
00141 static ULONG SeekOuter_Release(PassThruImpl *This)
00142 {
00143     if (This->pUnkOuter && This->bUnkOuterValid)
00144         return IUnknown_Release(This->pUnkOuter);
00145     return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
00146 }
00147 
00148 static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj)
00149 {
00150     ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);
00151 
00152     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
00153 
00154     return SeekOuter_QueryInterface(This, riid, ppvObj);
00155 }
00156 
00157 static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface)
00158 {
00159     ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);
00160 
00161     TRACE("(%p/%p)->()\n", This, iface);
00162 
00163     return SeekOuter_AddRef(This);
00164 }
00165 
00166 static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface)
00167 {
00168     ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);
00169 
00170     TRACE("(%p/%p)->()\n", This, iface);
00171 
00172     return SeekOuter_Release(This);
00173 }
00174 
00175 static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin)
00176 {
00177     ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface);
00178 
00179     TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin);
00180 
00181     if (This->pin)
00182         FIXME("Re-initializing?\n");
00183 
00184     This->renderer = renderer;
00185     This->pin = pin;
00186 
00187     return S_OK;
00188 }
00189 
00190 static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
00191 {
00192     SeekingPassThru_QueryInterface,
00193     SeekingPassThru_AddRef,
00194     SeekingPassThru_Release,
00195     SeekingPassThru_Init
00196 };
00197 
00198 HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj)
00199 {
00200     PassThruImpl *fimpl;
00201 
00202     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
00203 
00204     *ppObj = fimpl = CoTaskMemAlloc(sizeof(*fimpl));
00205     if (!fimpl)
00206         return E_OUTOFMEMORY;
00207 
00208     fimpl->pUnkOuter = pUnkOuter;
00209     fimpl->bUnkOuterValid = FALSE;
00210     fimpl->bAggregatable = FALSE;
00211     fimpl->IInner_vtbl = &IInner_VTable;
00212     fimpl->IPassThru_vtbl = &ISeekingPassThru_Vtbl;
00213     fimpl->IMediaSeeking_vtbl = &IMediaSeekingPassThru_Vtbl;
00214     fimpl->ref = 1;
00215     fimpl->pin = NULL;
00216     return S_OK;
00217 }
00218 
00219 typedef HRESULT (*SeekFunc)( IMediaSeeking *to, LPVOID arg );
00220 
00221 static HRESULT ForwardCmdSeek( PCRITICAL_SECTION crit_sect, IBaseFilter* from, SeekFunc fnSeek, LPVOID arg )
00222 {
00223     HRESULT hr = S_OK;
00224     HRESULT hr_return = S_OK;
00225     IEnumPins *enumpins = NULL;
00226     BOOL foundend = FALSE, allnotimpl = TRUE;
00227 
00228     hr = IBaseFilter_EnumPins( from, &enumpins );
00229     if (FAILED(hr))
00230         goto out;
00231 
00232     hr = IEnumPins_Reset( enumpins );
00233     while (hr == S_OK) {
00234         IPin *pin = NULL;
00235         hr = IEnumPins_Next( enumpins, 1, &pin, NULL );
00236         if (hr == VFW_E_ENUM_OUT_OF_SYNC)
00237         {
00238             hr = IEnumPins_Reset( enumpins );
00239             continue;
00240         }
00241         if (pin)
00242         {
00243             PIN_DIRECTION dir;
00244 
00245             IPin_QueryDirection( pin, &dir );
00246             if (dir == PINDIR_INPUT)
00247             {
00248                 IPin *connected = NULL;
00249 
00250                 IPin_ConnectedTo( pin, &connected );
00251                 if (connected)
00252                 {
00253                     HRESULT hr_local;
00254                     IMediaSeeking *seek = NULL;
00255 
00256                     hr_local = IPin_QueryInterface( connected, &IID_IMediaSeeking, (void**)&seek );
00257                     if (hr_local == S_OK)
00258                     {
00259                         foundend = TRUE;
00260                         if (crit_sect)
00261                         {
00262                             LeaveCriticalSection( crit_sect );
00263                             hr_local = fnSeek( seek , arg );
00264                             EnterCriticalSection( crit_sect );
00265                         }
00266                         else
00267                             hr_local = fnSeek( seek , arg );
00268 
00269                         if (hr_local != E_NOTIMPL)
00270                             allnotimpl = FALSE;
00271 
00272                         hr_return = updatehres( hr_return, hr_local );
00273                         IMediaSeeking_Release( seek );
00274                     }
00275                     IPin_Release(connected);
00276                 }
00277             }
00278             IPin_Release( pin );
00279         }
00280     }
00281     IEnumPins_Release( enumpins );
00282 
00283     if (foundend && allnotimpl)
00284         hr = E_NOTIMPL;
00285     else
00286         hr = hr_return;
00287 
00288 out:
00289     TRACE("Returning: %08x\n", hr);
00290     return hr;
00291 }
00292 
00293 
00294 HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeCurrent, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking, PCRITICAL_SECTION crit_sect)
00295 {
00296     assert(fnChangeStop && fnChangeCurrent && fnChangeRate);
00297 
00298     pSeeking->refCount = 1;
00299     pSeeking->pUserData = pUserData;
00300     pSeeking->fnChangeRate = fnChangeRate;
00301     pSeeking->fnChangeStop = fnChangeStop;
00302     pSeeking->fnChangeCurrent = fnChangeCurrent;
00303     pSeeking->dwCapabilities = AM_SEEKING_CanSeekForwards |
00304         AM_SEEKING_CanSeekBackwards |
00305         AM_SEEKING_CanSeekAbsolute |
00306         AM_SEEKING_CanGetStopPos |
00307         AM_SEEKING_CanGetDuration;
00308     pSeeking->llCurrent = 0;
00309     pSeeking->llStop = ((ULONGLONG)0x80000000) << 32;
00310     pSeeking->llDuration = pSeeking->llStop;
00311     pSeeking->dRate = 1.0;
00312     pSeeking->timeformat = TIME_FORMAT_MEDIA_TIME;
00313     pSeeking->crst = crit_sect;
00314 
00315     return S_OK;
00316 }
00317 
00318 struct pos_args {
00319     LONGLONG* current, *stop;
00320     DWORD curflags, stopflags;
00321 };
00322 
00323 static HRESULT fwd_setposition(IMediaSeeking *seek, LPVOID pargs)
00324 {
00325     struct pos_args *args = (void*)pargs;
00326 
00327     return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags);
00328 }
00329 
00330 static HRESULT fwd_checkcaps(IMediaSeeking *iface, LPVOID pcaps)
00331 {
00332     DWORD *caps = pcaps;
00333     return IMediaSeeking_CheckCapabilities(iface, caps);
00334 }
00335 
00336 static HRESULT fwd_settimeformat(IMediaSeeking *iface, LPVOID pformat)
00337 {
00338     const GUID *format = pformat;
00339     return IMediaSeeking_SetTimeFormat(iface, format);
00340 }
00341 
00342 static HRESULT fwd_getduration(IMediaSeeking *iface, LPVOID pdur)
00343 {
00344     LONGLONG *duration = pdur;
00345     LONGLONG mydur = *duration;
00346     HRESULT hr;
00347 
00348     hr = IMediaSeeking_GetDuration(iface, &mydur);
00349     if (FAILED(hr))
00350         return hr;
00351 
00352     if ((mydur < *duration) || (*duration < 0 && mydur > 0))
00353         *duration = mydur;
00354     return hr;
00355 }
00356 
00357 static HRESULT fwd_getstopposition(IMediaSeeking *iface, LPVOID pdur)
00358 {
00359     LONGLONG *duration = pdur;
00360     LONGLONG mydur = *duration;
00361     HRESULT hr;
00362 
00363     hr = IMediaSeeking_GetStopPosition(iface, &mydur);
00364     if (FAILED(hr))
00365         return hr;
00366 
00367     if ((mydur < *duration) || (*duration < 0 && mydur > 0))
00368         *duration = mydur;
00369     return hr;
00370 }
00371 
00372 static HRESULT fwd_getcurposition(IMediaSeeking *iface, LPVOID pdur)
00373 {
00374     LONGLONG *duration = pdur;
00375     LONGLONG mydur = *duration;
00376     HRESULT hr;
00377 
00378     hr = IMediaSeeking_GetCurrentPosition(iface, &mydur);
00379     if (FAILED(hr))
00380         return hr;
00381 
00382     if ((mydur < *duration) || (*duration < 0 && mydur > 0))
00383         *duration = mydur;
00384     return hr;
00385 }
00386 
00387 static HRESULT fwd_setrate(IMediaSeeking *iface, LPVOID prate)
00388 {
00389     double *rate = prate;
00390 
00391     HRESULT hr;
00392 
00393     hr = IMediaSeeking_SetRate(iface, *rate);
00394     if (FAILED(hr))
00395         return hr;
00396 
00397     return hr;
00398 }
00399 
00400 
00401 HRESULT WINAPI MediaSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
00402 {
00403     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00404 
00405     TRACE("(%p)\n", pCapabilities);
00406 
00407     *pCapabilities = This->dwCapabilities;
00408 
00409     return S_OK;
00410 }
00411 
00412 HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
00413 {
00414     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00415     HRESULT hr;
00416     DWORD dwCommonCaps;
00417 
00418     TRACE("(%p)\n", pCapabilities);
00419 
00420     if (!pCapabilities)
00421         return E_POINTER;
00422 
00423     EnterCriticalSection(This->crst);
00424     hr = ForwardCmdSeek(This->crst, This->pUserData, fwd_checkcaps, pCapabilities);
00425     LeaveCriticalSection(This->crst);
00426     if (FAILED(hr) && hr != E_NOTIMPL)
00427         return hr;
00428 
00429     dwCommonCaps = *pCapabilities & This->dwCapabilities;
00430 
00431     if (!dwCommonCaps)
00432         hr = E_FAIL;
00433     else
00434         hr = (*pCapabilities == dwCommonCaps) ?  S_OK : S_FALSE;
00435     *pCapabilities = dwCommonCaps;
00436 
00437     return hr;
00438 }
00439 
00440 HRESULT WINAPI MediaSeekingImpl_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
00441 {
00442     TRACE("(%s)\n", qzdebugstr_guid(pFormat));
00443 
00444     return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE);
00445 }
00446 
00447 HRESULT WINAPI MediaSeekingImpl_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
00448 {
00449     TRACE("(%s)\n", qzdebugstr_guid(pFormat));
00450 
00451     *pFormat = TIME_FORMAT_MEDIA_TIME;
00452     return S_OK;
00453 }
00454 
00455 HRESULT WINAPI MediaSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
00456 {
00457     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00458     TRACE("(%s)\n", qzdebugstr_guid(pFormat));
00459 
00460     EnterCriticalSection(This->crst);
00461     *pFormat = This->timeformat;
00462     LeaveCriticalSection(This->crst);
00463 
00464     return S_OK;
00465 }
00466 
00467 HRESULT WINAPI MediaSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
00468 {
00469     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00470     HRESULT hr = S_OK;
00471 
00472     TRACE("(%s)\n", qzdebugstr_guid(pFormat));
00473 
00474     EnterCriticalSection(This->crst);
00475     if (!IsEqualIID(pFormat, &This->timeformat))
00476         hr = S_FALSE;
00477     LeaveCriticalSection(This->crst);
00478 
00479     return hr;
00480 }
00481 
00482 
00483 HRESULT WINAPI MediaSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
00484 {
00485     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00486     TRACE("(%s)\n", qzdebugstr_guid(pFormat));
00487 
00488     EnterCriticalSection(This->crst);
00489     ForwardCmdSeek(This->crst, This->pUserData, fwd_settimeformat, (LPVOID)pFormat);
00490     LeaveCriticalSection(This->crst);
00491 
00492     return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE);
00493 }
00494 
00495 
00496 HRESULT WINAPI MediaSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
00497 {
00498     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00499 
00500     TRACE("(%p)\n", pDuration);
00501 
00502     EnterCriticalSection(This->crst);
00503     *pDuration = This->llDuration;
00504     ForwardCmdSeek(This->crst, This->pUserData, fwd_getduration, pDuration);
00505     LeaveCriticalSection(This->crst);
00506 
00507     return S_OK;
00508 }
00509 
00510 HRESULT WINAPI MediaSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
00511 {
00512     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00513 
00514     TRACE("(%p)\n", pStop);
00515 
00516     EnterCriticalSection(This->crst);
00517     *pStop = This->llStop;
00518     ForwardCmdSeek(This->crst, This->pUserData, fwd_getstopposition, pStop);
00519     LeaveCriticalSection(This->crst);
00520 
00521     return S_OK;
00522 }
00523 
00524 /* FIXME: Make use of the info the filter should expose */
00525 HRESULT WINAPI MediaSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
00526 {
00527     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00528 
00529     TRACE("(%p)\n", pCurrent);
00530 
00531     EnterCriticalSection(This->crst);
00532     *pCurrent = This->llCurrent;
00533     ForwardCmdSeek(This->crst, This->pUserData, fwd_getcurposition, pCurrent);
00534     LeaveCriticalSection(This->crst);
00535 
00536     return S_OK;
00537 }
00538 
00539 HRESULT WINAPI MediaSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
00540 {
00541     if (IsEqualIID(pTargetFormat, &TIME_FORMAT_MEDIA_TIME) && IsEqualIID(pSourceFormat, &TIME_FORMAT_MEDIA_TIME))
00542     {
00543         *pTarget = Source;
00544         return S_OK;
00545     }
00546     /* FIXME: clear pTarget? */
00547     return E_INVALIDARG;
00548 }
00549 
00550 static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD dwFlags)
00551 {
00552     switch (dwFlags & AM_SEEKING_PositioningBitsMask)
00553     {
00554     case AM_SEEKING_NoPositioning:
00555         return value;
00556     case AM_SEEKING_AbsolutePositioning:
00557         return *pModifier;
00558     case AM_SEEKING_RelativePositioning:
00559     case AM_SEEKING_IncrementalPositioning:
00560         return value + *pModifier;
00561     default:
00562         assert(FALSE);
00563         return 0;
00564     }
00565 }
00566 
00567 HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
00568 {
00569     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00570     BOOL bChangeCurrent = FALSE, bChangeStop = FALSE;
00571     LONGLONG llNewCurrent, llNewStop;
00572     struct pos_args args;
00573 
00574     TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags);
00575 
00576     args.current = pCurrent;
00577     args.stop = pStop;
00578     args.curflags = dwCurrentFlags;
00579     args.stopflags = dwStopFlags;
00580 
00581     EnterCriticalSection(This->crst);
00582 
00583     llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags);
00584     llNewStop = Adjust(This->llStop, pStop, dwStopFlags);
00585 
00586     if (pCurrent)
00587         bChangeCurrent = TRUE;
00588     if (llNewStop != This->llStop)
00589         bChangeStop = TRUE;
00590 
00591     TRACE("Old: %u, New: %u\n", (DWORD)(This->llCurrent/10000000), (DWORD)(llNewCurrent/10000000));
00592 
00593     This->llCurrent = llNewCurrent;
00594     This->llStop = llNewStop;
00595 
00596     if (pCurrent && (dwCurrentFlags & AM_SEEKING_ReturnTime))
00597         *pCurrent = llNewCurrent;
00598     if (pStop && (dwStopFlags & AM_SEEKING_ReturnTime))
00599         *pStop = llNewStop;
00600 
00601     ForwardCmdSeek(This->crst, This->pUserData, fwd_setposition, &args);
00602     LeaveCriticalSection(This->crst);
00603 
00604     if (bChangeCurrent)
00605         This->fnChangeCurrent(This->pUserData);
00606     if (bChangeStop)
00607         This->fnChangeStop(This->pUserData);
00608 
00609     return S_OK;
00610 }
00611 
00612 HRESULT WINAPI MediaSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
00613 {
00614     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00615 
00616     TRACE("(%p, %p)\n", pCurrent, pStop);
00617 
00618     EnterCriticalSection(This->crst);
00619     *pCurrent = This->llCurrent;
00620     *pStop = This->llStop;
00621     LeaveCriticalSection(This->crst);
00622 
00623     return S_OK;
00624 }
00625 
00626 HRESULT WINAPI MediaSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
00627 {
00628     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00629 
00630     TRACE("(%p, %p)\n", pEarliest, pLatest);
00631 
00632     EnterCriticalSection(This->crst);
00633     *pEarliest = 0;
00634     *pLatest = This->llDuration;
00635     LeaveCriticalSection(This->crst);
00636 
00637     return S_OK;
00638 }
00639 
00640 HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate)
00641 {
00642     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00643     BOOL bChangeRate = (dRate != This->dRate);
00644     HRESULT hr = S_OK;
00645 
00646     TRACE("(%e)\n", dRate);
00647 
00648     if (dRate > 100 || dRate < .001)
00649     {
00650         FIXME("Excessive rate %e, ignoring\n", dRate);
00651         return VFW_E_UNSUPPORTED_AUDIO;
00652     }
00653 
00654     EnterCriticalSection(This->crst);
00655     This->dRate = dRate;
00656     if (bChangeRate)
00657         hr = This->fnChangeRate(This->pUserData);
00658     ForwardCmdSeek(This->crst, This->pUserData, fwd_setrate, &dRate);
00659     LeaveCriticalSection(This->crst);
00660 
00661     return hr;
00662 }
00663 
00664 HRESULT WINAPI MediaSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate)
00665 {
00666     MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
00667 
00668     TRACE("(%p)\n", dRate);
00669 
00670     EnterCriticalSection(This->crst);
00671     /* Forward? */
00672     *dRate = This->dRate;
00673     LeaveCriticalSection(This->crst);
00674 
00675     return S_OK;
00676 }
00677 
00678 HRESULT WINAPI MediaSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
00679 {
00680     TRACE("(%p)\n", pPreroll);
00681 
00682     *pPreroll = 0;
00683     return S_OK;
00684 }
00685 
00686 static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj)
00687 {
00688     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00689 
00690     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
00691 
00692     return SeekOuter_QueryInterface(This, riid, ppvObj);
00693 }
00694 
00695 static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface)
00696 {
00697     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00698 
00699     TRACE("(%p/%p)->()\n", iface, This);
00700 
00701     return SeekOuter_AddRef(This);
00702 }
00703 
00704 static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface)
00705 {
00706     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00707 
00708     TRACE("(%p/%p)->()\n", iface, This);
00709 
00710     return SeekOuter_Release(This);
00711 }
00712 
00713 static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
00714 {
00715     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00716 
00717     TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
00718 
00719     FIXME("stub\n");
00720     return E_NOTIMPL;
00721 }
00722 
00723 static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities)
00724 {
00725     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00726 
00727     TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities);
00728 
00729     if (!pCapabilities)
00730         return E_POINTER;
00731 
00732     FIXME("stub\n");
00733     return E_NOTIMPL;
00734 }
00735 
00736 static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat)
00737 {
00738     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00739     TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat));
00740 
00741     FIXME("stub\n");
00742     return E_NOTIMPL;
00743 }
00744 
00745 static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat)
00746 {
00747     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00748     TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
00749 
00750     FIXME("stub\n");
00751     return E_NOTIMPL;
00752 }
00753 
00754 static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat)
00755 {
00756     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00757     TRACE("(%p/%p)->(%p)\n", iface, This, pFormat);
00758 
00759     FIXME("stub\n");
00760     return E_NOTIMPL;
00761 }
00762 
00763 static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
00764 {
00765     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00766 
00767     TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat));
00768 
00769     FIXME("stub\n");
00770     return E_NOTIMPL;
00771 }
00772 
00773 
00774 static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat)
00775 {
00776     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00777     TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat));
00778 
00779     FIXME("stub\n");
00780     return E_NOTIMPL;
00781 }
00782 
00783 
00784 static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration)
00785 {
00786     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00787     PIN_INFO info;
00788     HRESULT hr;
00789 
00790     TRACE("(%p/%p)->(%p)\n", iface, This, pDuration);
00791 
00792     IPin_QueryPinInfo(This->pin, &info);
00793 
00794     hr = ForwardCmdSeek(NULL, info.pFilter, fwd_getduration, pDuration);
00795     IBaseFilter_Release(info.pFilter);
00796 
00797     return hr;
00798 }
00799 
00800 static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop)
00801 {
00802     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00803 
00804     TRACE("(%p/%p)->(%p)\n", iface, This, pStop);
00805 
00806     FIXME("stub\n");
00807     return E_NOTIMPL;
00808 }
00809 
00810 /* FIXME: Make use of the info the filter should expose */
00811 static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent)
00812 {
00813     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00814 
00815     TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent);
00816 
00817     FIXME("stub\n");
00818     return E_NOTIMPL;
00819 }
00820 
00821 static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat)
00822 {
00823     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00824 
00825     TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat));
00826 
00827     FIXME("stub\n");
00828     return E_NOTIMPL;
00829 }
00830 
00831 static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
00832 {
00833     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00834     struct pos_args args;
00835     PIN_INFO info;
00836     HRESULT hr;
00837 
00838     TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
00839     args.current = pCurrent;
00840     args.stop = pStop;
00841     args.curflags = dwCurrentFlags;
00842     args.stopflags = dwStopFlags;
00843 
00844     IPin_QueryPinInfo(This->pin, &info);
00845 
00846     hr = ForwardCmdSeek(NULL, info.pFilter, fwd_setposition, &args);
00847     IBaseFilter_Release(info.pFilter);
00848     return hr;
00849 }
00850 
00851 static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop)
00852 {
00853     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00854 
00855     TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop);
00856 
00857     FIXME("stub\n");
00858     return E_NOTIMPL;
00859 }
00860 
00861 static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest)
00862 {
00863     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00864 
00865     TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest);
00866 
00867     FIXME("stub\n");
00868     return E_NOTIMPL;
00869 }
00870 
00871 static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate)
00872 {
00873     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00874 
00875     TRACE("(%p/%p)->(%e)\n", iface, This, dRate);
00876 
00877     FIXME("stub\n");
00878     return E_NOTIMPL;
00879 }
00880 
00881 static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate)
00882 {
00883     ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface);
00884 
00885     TRACE("(%p/%p)->(%p)\n", iface, This, dRate);
00886 
00887     FIXME("stub\n");
00888     return E_NOTIMPL;
00889 }
00890 
00891 static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll)
00892 {
00893     TRACE("(%p)\n", pPreroll);
00894 
00895     FIXME("stub\n");
00896     return E_NOTIMPL;
00897 }
00898 
00899 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
00900 {
00901     MediaSeekingPassThru_QueryInterface,
00902     MediaSeekingPassThru_AddRef,
00903     MediaSeekingPassThru_Release,
00904     MediaSeekingPassThru_GetCapabilities,
00905     MediaSeekingPassThru_CheckCapabilities,
00906     MediaSeekingPassThru_IsFormatSupported,
00907     MediaSeekingPassThru_QueryPreferredFormat,
00908     MediaSeekingPassThru_GetTimeFormat,
00909     MediaSeekingPassThru_IsUsingTimeFormat,
00910     MediaSeekingPassThru_SetTimeFormat,
00911     MediaSeekingPassThru_GetDuration,
00912     MediaSeekingPassThru_GetStopPosition,
00913     MediaSeekingPassThru_GetCurrentPosition,
00914     MediaSeekingPassThru_ConvertTimeFormat,
00915     MediaSeekingPassThru_SetPositions,
00916     MediaSeekingPassThru_GetPositions,
00917     MediaSeekingPassThru_GetAvailable,
00918     MediaSeekingPassThru_SetRate,
00919     MediaSeekingPassThru_GetRate,
00920     MediaSeekingPassThru_GetPreroll
00921 };

Generated on Mon May 28 2012 04:16:36 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.