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

parser.c
Go to the documentation of this file.
00001 /*
00002  * Parser (Base for parsers and splitters)
00003  *
00004  * Copyright 2003 Robert Shearman
00005  * Copyright 2004-2005 Christian Costa
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "quartz_private.h"
00023 #include "control_private.h"
00024 #include "pin.h"
00025 
00026 #include "vfwmsgs.h"
00027 #include "amvideo.h"
00028 
00029 #include "wine/unicode.h"
00030 #include "wine/debug.h"
00031 
00032 #include <math.h>
00033 #include <assert.h>
00034 
00035 #include "parser.h"
00036 
00037 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
00038 
00039 static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
00040 static const IMediaSeekingVtbl Parser_Seeking_Vtbl;
00041 static const IPinVtbl Parser_OutputPin_Vtbl;
00042 static const IPinVtbl Parser_InputPin_Vtbl;
00043 
00044 static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt);
00045 static HRESULT Parser_ChangeCurrent(IBaseFilter *iface);
00046 static HRESULT Parser_ChangeStop(IBaseFilter *iface);
00047 static HRESULT Parser_ChangeRate(IBaseFilter *iface);
00048 
00049 static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
00050 {
00051     return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl));
00052 }
00053 
00054 
00055 HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, const CLSID* pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, STOPPROCESSPROC fnDone, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate)
00056 {
00057     HRESULT hr;
00058     PIN_INFO piInput;
00059 
00060     /* pTransformFilter is already allocated */
00061     pParser->clsid = *pClsid;
00062     pParser->lpVtbl = Parser_Vtbl;
00063     pParser->refCount = 1;
00064     InitializeCriticalSection(&pParser->csFilter);
00065     pParser->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter");
00066     pParser->state = State_Stopped;
00067     pParser->pClock = NULL;
00068     pParser->fnDisconnect = fnDisconnect;
00069     ZeroMemory(&pParser->filterInfo, sizeof(FILTER_INFO));
00070     pParser->lastpinchange = GetTickCount();
00071 
00072     pParser->cStreams = 0;
00073     pParser->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
00074 
00075     /* construct input pin */
00076     piInput.dir = PINDIR_INPUT;
00077     piInput.pFilter = (IBaseFilter *)pParser;
00078     lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
00079 
00080     if (!current)
00081         current = Parser_ChangeCurrent;
00082 
00083     if (!stop)
00084         stop = Parser_ChangeStop;
00085 
00086     if (!rate)
00087         rate = Parser_ChangeRate;
00088 
00089     MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter);
00090     pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
00091 
00092     hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, fnDone, &pParser->csFilter, (IPin **)&pParser->pInputPin);
00093 
00094     if (SUCCEEDED(hr))
00095     {
00096         pParser->ppPins[0] = (IPin *)pParser->pInputPin;
00097         pParser->pInputPin->fnPreConnect = fnPreConnect;
00098     }
00099     else
00100     {
00101         CoTaskMemFree(pParser->ppPins);
00102         pParser->csFilter.DebugInfo->Spare[0] = 0;
00103         DeleteCriticalSection(&pParser->csFilter);
00104         CoTaskMemFree(pParser);
00105     }
00106 
00107     return hr;
00108 }
00109 
00110 HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
00111 {
00112     ParserImpl *This = (ParserImpl *)iface;
00113     TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
00114 
00115     *ppv = NULL;
00116 
00117     if (IsEqualIID(riid, &IID_IUnknown))
00118         *ppv = This;
00119     else if (IsEqualIID(riid, &IID_IPersist))
00120         *ppv = This;
00121     else if (IsEqualIID(riid, &IID_IMediaFilter))
00122         *ppv = This;
00123     else if (IsEqualIID(riid, &IID_IBaseFilter))
00124         *ppv = This;
00125     else if (IsEqualIID(riid, &IID_IMediaSeeking))
00126         *ppv = &This->mediaSeeking;
00127 
00128     if (*ppv)
00129     {
00130         IUnknown_AddRef((IUnknown *)(*ppv));
00131         return S_OK;
00132     }
00133 
00134     if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow))
00135         FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
00136 
00137     return E_NOINTERFACE;
00138 }
00139 
00140 ULONG WINAPI Parser_AddRef(IBaseFilter * iface)
00141 {
00142     ParserImpl *This = (ParserImpl *)iface;
00143     ULONG refCount = InterlockedIncrement(&This->refCount);
00144 
00145     TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
00146 
00147     return refCount;
00148 }
00149 
00150 void Parser_Destroy(ParserImpl *This)
00151 {
00152     IPin *connected = NULL;
00153     ULONG pinref;
00154 
00155     assert(!This->refCount);
00156     PullPin_WaitForStateChange(This->pInputPin, INFINITE);
00157 
00158     if (This->pClock)
00159         IReferenceClock_Release(This->pClock);
00160 
00161     /* Don't need to clean up output pins, freeing input pin will do that */
00162     IPin_ConnectedTo((IPin *)This->pInputPin, &connected);
00163     if (connected)
00164     {
00165         assert(IPin_Disconnect(connected) == S_OK);
00166         IPin_Release(connected);
00167         assert(IPin_Disconnect((IPin *)This->pInputPin) == S_OK);
00168     }
00169     pinref = IPin_Release((IPin *)This->pInputPin);
00170     if (pinref)
00171     {
00172         /* Valgrind could find this, if I kill it here */
00173         ERR("pinref should be null, is %u, destroying anyway\n", pinref);
00174         assert((LONG)pinref > 0);
00175 
00176         while (pinref)
00177             pinref = IPin_Release((IPin *)This->pInputPin);
00178     }
00179 
00180     CoTaskMemFree(This->ppPins);
00181     This->lpVtbl = NULL;
00182 
00183     This->csFilter.DebugInfo->Spare[0] = 0;
00184     DeleteCriticalSection(&This->csFilter);
00185 
00186     TRACE("Destroying parser\n");
00187     CoTaskMemFree(This);
00188 }
00189 
00190 ULONG WINAPI Parser_Release(IBaseFilter * iface)
00191 {
00192     ParserImpl *This = (ParserImpl *)iface;
00193     ULONG refCount = InterlockedDecrement(&This->refCount);
00194 
00195     TRACE("(%p)->() Release from %d\n", This, refCount + 1);
00196 
00197     if (!refCount)
00198         Parser_Destroy(This);
00199 
00200     return refCount;
00201 }
00202 
00205 HRESULT WINAPI Parser_GetClassID(IBaseFilter * iface, CLSID * pClsid)
00206 {
00207     ParserImpl *This = (ParserImpl *)iface;
00208 
00209     TRACE("(%p)\n", pClsid);
00210 
00211     *pClsid = This->clsid;
00212 
00213     return S_OK;
00214 }
00215 
00218 HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
00219 {
00220     ParserImpl *This = (ParserImpl *)iface;
00221     PullPin *pin = (PullPin *)This->ppPins[0];
00222     ULONG i;
00223 
00224     TRACE("()\n");
00225 
00226     EnterCriticalSection(&pin->thread_lock);
00227 
00228     IAsyncReader_BeginFlush(This->pInputPin->pReader);
00229     EnterCriticalSection(&This->csFilter);
00230 
00231     if (This->state == State_Stopped)
00232     {
00233         LeaveCriticalSection(&This->csFilter);
00234         IAsyncReader_EndFlush(This->pInputPin->pReader);
00235         LeaveCriticalSection(&pin->thread_lock);
00236         return S_OK;
00237     }
00238 
00239     This->state = State_Stopped;
00240 
00241     for (i = 1; i < (This->cStreams + 1); i++)
00242     {
00243         OutputPin_DecommitAllocator((OutputPin *)This->ppPins[i]);
00244     }
00245 
00246     LeaveCriticalSection(&This->csFilter);
00247 
00248     PullPin_PauseProcessing(This->pInputPin);
00249     PullPin_WaitForStateChange(This->pInputPin, INFINITE);
00250     IAsyncReader_EndFlush(This->pInputPin->pReader);
00251 
00252     LeaveCriticalSection(&pin->thread_lock);
00253     return S_OK;
00254 }
00255 
00256 HRESULT WINAPI Parser_Pause(IBaseFilter * iface)
00257 {
00258     HRESULT hr = S_OK;
00259     ParserImpl *This = (ParserImpl *)iface;
00260     PullPin *pin = (PullPin *)This->ppPins[0];
00261 
00262     TRACE("()\n");
00263 
00264     EnterCriticalSection(&pin->thread_lock);
00265     EnterCriticalSection(&This->csFilter);
00266 
00267     if (This->state == State_Paused)
00268     {
00269         LeaveCriticalSection(&This->csFilter);
00270         LeaveCriticalSection(&pin->thread_lock);
00271         return S_OK;
00272     }
00273 
00274     if (This->state == State_Stopped)
00275     {
00276         LeaveCriticalSection(&This->csFilter);
00277         hr = IBaseFilter_Run(iface, -1);
00278         EnterCriticalSection(&This->csFilter);
00279     }
00280 
00281     if (SUCCEEDED(hr))
00282         This->state = State_Paused;
00283 
00284     LeaveCriticalSection(&This->csFilter);
00285     LeaveCriticalSection(&pin->thread_lock);
00286 
00287     return hr;
00288 }
00289 
00290 HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
00291 {
00292     HRESULT hr = S_OK;
00293     ParserImpl *This = (ParserImpl *)iface;
00294     PullPin *pin = (PullPin *)This->ppPins[0];
00295 
00296     ULONG i;
00297 
00298     TRACE("(%s)\n", wine_dbgstr_longlong(tStart));
00299 
00300     EnterCriticalSection(&pin->thread_lock);
00301     EnterCriticalSection(&This->csFilter);
00302     {
00303         HRESULT hr_any = VFW_E_NOT_CONNECTED;
00304 
00305         if (This->state == State_Running || This->state == State_Paused)
00306         {
00307             This->state = State_Running;
00308             LeaveCriticalSection(&This->csFilter);
00309             LeaveCriticalSection(&pin->thread_lock);
00310             return S_OK;
00311         }
00312 
00313         This->rtStreamStart = tStart;
00314 
00315         for (i = 1; i < (This->cStreams + 1); i++)
00316         {
00317             hr = OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]);
00318             if (SUCCEEDED(hr))
00319                 hr_any = hr;
00320         }
00321 
00322         hr = hr_any;
00323         if (SUCCEEDED(hr))
00324         {
00325             LeaveCriticalSection(&This->csFilter);
00326             hr = PullPin_StartProcessing(This->pInputPin);
00327             EnterCriticalSection(&This->csFilter);
00328         }
00329 
00330         if (SUCCEEDED(hr))
00331             This->state = State_Running;
00332     }
00333     LeaveCriticalSection(&This->csFilter);
00334     LeaveCriticalSection(&pin->thread_lock);
00335 
00336     return hr;
00337 }
00338 
00339 HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
00340 {
00341     ParserImpl *This = (ParserImpl *)iface;
00342     PullPin *pin = (PullPin *)This->ppPins[0];
00343     HRESULT hr = S_OK;
00344 
00345     TRACE("(%d, %p)\n", dwMilliSecsTimeout, pState);
00346 
00347     EnterCriticalSection(&pin->thread_lock);
00348     EnterCriticalSection(&This->csFilter);
00349     {
00350         *pState = This->state;
00351     }
00352     LeaveCriticalSection(&This->csFilter);
00353 
00354     if (This->pInputPin && (PullPin_WaitForStateChange(This->pInputPin, dwMilliSecsTimeout) == S_FALSE))
00355         hr = VFW_S_STATE_INTERMEDIATE;
00356     LeaveCriticalSection(&pin->thread_lock);
00357 
00358     return hr;
00359 }
00360 
00361 HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
00362 {
00363     ParserImpl *This = (ParserImpl *)iface;
00364     PullPin *pin = (PullPin *)This->ppPins[0];
00365 
00366     TRACE("(%p)\n", pClock);
00367 
00368     EnterCriticalSection(&pin->thread_lock);
00369     EnterCriticalSection(&This->csFilter);
00370     {
00371         if (This->pClock)
00372             IReferenceClock_Release(This->pClock);
00373         This->pClock = pClock;
00374         if (This->pClock)
00375             IReferenceClock_AddRef(This->pClock);
00376     }
00377     LeaveCriticalSection(&This->csFilter);
00378     LeaveCriticalSection(&pin->thread_lock);
00379 
00380     return S_OK;
00381 }
00382 
00383 HRESULT WINAPI Parser_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
00384 {
00385     ParserImpl *This = (ParserImpl *)iface;
00386 
00387     TRACE("(%p)\n", ppClock);
00388 
00389     EnterCriticalSection(&This->csFilter);
00390     {
00391         *ppClock = This->pClock;
00392         if (This->pClock)
00393             IReferenceClock_AddRef(This->pClock);
00394     }
00395     LeaveCriticalSection(&This->csFilter);
00396     
00397     return S_OK;
00398 }
00399 
00402 /* FIXME: WRONG */
00403 static HRESULT Parser_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
00404 {
00405     ParserImpl *This = (ParserImpl *)iface;
00406 
00407     *lastsynctick = This->lastpinchange;
00408 
00409     TRACE("Asking for pos %x\n", pos);
00410 
00411     /* Input pin also has a pin, hence the > and not >= */
00412     if (pos > This->cStreams)
00413         return S_FALSE;
00414 
00415     *pin = This->ppPins[pos];
00416     IPin_AddRef(*pin);
00417     return S_OK;
00418 }
00419 
00420 HRESULT WINAPI Parser_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
00421 {
00422     ParserImpl *This = (ParserImpl *)iface;
00423 
00424     TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
00425 
00426     return IEnumPinsImpl_Construct(ppEnum, Parser_GetPin, iface);
00427 }
00428 
00429 HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
00430 {
00431     FIXME("(%p)->(%s,%p)\n", iface, debugstr_w(Id), ppPin);
00432 
00433     /* FIXME: critical section */
00434 
00435     return E_NOTIMPL;
00436 }
00437 
00438 HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
00439 {
00440     ParserImpl *This = (ParserImpl *)iface;
00441 
00442     TRACE("(%p)\n", pInfo);
00443 
00444     strcpyW(pInfo->achName, This->filterInfo.achName);
00445     pInfo->pGraph = This->filterInfo.pGraph;
00446 
00447     if (pInfo->pGraph)
00448         IFilterGraph_AddRef(pInfo->pGraph);
00449     
00450     return S_OK;
00451 }
00452 
00453 HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
00454 {
00455     HRESULT hr = S_OK;
00456     ParserImpl *This = (ParserImpl *)iface;
00457 
00458     TRACE("(%p, %s)\n", pGraph, debugstr_w(pName));
00459 
00460     EnterCriticalSection(&This->csFilter);
00461     {
00462         if (pName)
00463             strcpyW(This->filterInfo.achName, pName);
00464         else
00465             *This->filterInfo.achName = '\0';
00466         This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
00467     }
00468     LeaveCriticalSection(&This->csFilter);
00469 
00470     return hr;
00471 }
00472 
00473 HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
00474 {
00475     TRACE("(%p)\n", pVendorInfo);
00476     return E_NOTIMPL;
00477 }
00478 
00479 HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt)
00480 {
00481     IPin ** ppOldPins;
00482     HRESULT hr;
00483 
00484     ppOldPins = This->ppPins;
00485 
00486     This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
00487     memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
00488 
00489     hr = OutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, Parser_OutputPin_QueryAccept, &This->csFilter, This->ppPins + (This->cStreams + 1));
00490 
00491     if (SUCCEEDED(hr))
00492     {
00493         IPin *pPin = This->ppPins[This->cStreams + 1];
00494         Parser_OutputPin *pin = (Parser_OutputPin *)pPin;
00495         pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00496         CopyMediaType(pin->pmt, amt);
00497         pin->dwSamplesProcessed = 0;
00498 
00499         pin->pin.pin.pUserData = This->ppPins[This->cStreams + 1];
00500         pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
00501         pin->pin.custom_allocator = 1;
00502         This->cStreams++;
00503         This->lastpinchange = GetTickCount();
00504         CoTaskMemFree(ppOldPins);
00505     }
00506     else
00507     {
00508         CoTaskMemFree(This->ppPins);
00509         This->ppPins = ppOldPins;
00510         ERR("Failed with error %x\n", hr);
00511     }
00512 
00513     return hr;
00514 }
00515 
00516 static HRESULT Parser_RemoveOutputPins(ParserImpl * This)
00517 {
00518     /* NOTE: should be in critical section when calling this function */
00519     HRESULT hr;
00520     ULONG i;
00521     IPin ** ppOldPins = This->ppPins;
00522 
00523     TRACE("(%p)\n", This);
00524 
00525     /* reduce the pin array down to 1 (just our input pin) */
00526     This->ppPins = CoTaskMemAlloc(sizeof(IPin *) * 1);
00527     memcpy(This->ppPins, ppOldPins, sizeof(IPin *) * 1);
00528 
00529     for (i = 0; i < This->cStreams; i++)
00530     {
00531         hr = OutputPin_DeliverDisconnect((OutputPin *)ppOldPins[i + 1]);
00532         TRACE("Disconnect: %08x\n", hr);
00533         IPin_Release(ppOldPins[i + 1]);
00534     }
00535 
00536     This->lastpinchange = GetTickCount();
00537     This->cStreams = 0;
00538     CoTaskMemFree(ppOldPins);
00539 
00540     return S_OK;
00541 }
00542 
00543 static HRESULT Parser_ChangeCurrent(IBaseFilter *iface)
00544 {
00545     FIXME("(%p) filter hasn't implemented current position change!\n", iface);
00546     return S_OK;
00547 }
00548 
00549 static HRESULT Parser_ChangeStop(IBaseFilter *iface)
00550 {
00551     FIXME("(%p) filter hasn't implemented stop position change!\n", iface);
00552     return S_OK;
00553 }
00554 
00555 static HRESULT Parser_ChangeRate(IBaseFilter *iface)
00556 {
00557     FIXME("(%p) filter hasn't implemented rate change!\n", iface);
00558     return S_OK;
00559 }
00560 
00561 
00562 static HRESULT WINAPI Parser_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv)
00563 {
00564     ParserImpl *This = impl_from_IMediaSeeking(iface);
00565 
00566     return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
00567 }
00568 
00569 static ULONG WINAPI Parser_Seeking_AddRef(IMediaSeeking * iface)
00570 {
00571     ParserImpl *This = impl_from_IMediaSeeking(iface);
00572 
00573     return IUnknown_AddRef((IUnknown *)This);
00574 }
00575 
00576 static ULONG WINAPI Parser_Seeking_Release(IMediaSeeking * iface)
00577 {
00578     ParserImpl *This = impl_from_IMediaSeeking(iface);
00579 
00580     return IUnknown_Release((IUnknown *)This);
00581 }
00582 
00583 static const IMediaSeekingVtbl Parser_Seeking_Vtbl =
00584 {
00585     Parser_Seeking_QueryInterface,
00586     Parser_Seeking_AddRef,
00587     Parser_Seeking_Release,
00588     MediaSeekingImpl_GetCapabilities,
00589     MediaSeekingImpl_CheckCapabilities,
00590     MediaSeekingImpl_IsFormatSupported,
00591     MediaSeekingImpl_QueryPreferredFormat,
00592     MediaSeekingImpl_GetTimeFormat,
00593     MediaSeekingImpl_IsUsingTimeFormat,
00594     MediaSeekingImpl_SetTimeFormat,
00595     MediaSeekingImpl_GetDuration,
00596     MediaSeekingImpl_GetStopPosition,
00597     MediaSeekingImpl_GetCurrentPosition,
00598     MediaSeekingImpl_ConvertTimeFormat,
00599     MediaSeekingImpl_SetPositions,
00600     MediaSeekingImpl_GetPositions,
00601     MediaSeekingImpl_GetAvailable,
00602     MediaSeekingImpl_SetRate,
00603     MediaSeekingImpl_GetRate,
00604     MediaSeekingImpl_GetPreroll
00605 };
00606 
00607 static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
00608 {
00609     Parser_OutputPin *This = (Parser_OutputPin *)iface;
00610 
00611     TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
00612 
00613     *ppv = NULL;
00614 
00615     if (IsEqualIID(riid, &IID_IUnknown))
00616         *ppv = iface;
00617     else if (IsEqualIID(riid, &IID_IPin))
00618         *ppv = iface;
00619     else if (IsEqualIID(riid, &IID_IMediaSeeking))
00620     {
00621         return IBaseFilter_QueryInterface(This->pin.pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv);
00622     }
00623 
00624     if (*ppv)
00625     {
00626         IUnknown_AddRef((IUnknown *)(*ppv));
00627         return S_OK;
00628     }
00629 
00630     FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
00631 
00632     return E_NOINTERFACE;
00633 }
00634 
00635 static ULONG WINAPI Parser_OutputPin_Release(IPin * iface)
00636 {
00637     Parser_OutputPin *This = (Parser_OutputPin *)iface;
00638     ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount);
00639     
00640     TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
00641 
00642     if (!refCount)
00643     {
00644         FreeMediaType(This->pmt);
00645         CoTaskMemFree(This->pmt);
00646         FreeMediaType(&This->pin.pin.mtCurrent);
00647         CoTaskMemFree(This);
00648         return 0;
00649     }
00650     return refCount;
00651 }
00652 
00653 static HRESULT WINAPI Parser_OutputPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
00654 {
00655     ENUMMEDIADETAILS emd;
00656     Parser_OutputPin *This = (Parser_OutputPin *)iface;
00657 
00658     TRACE("(%p)\n", ppEnum);
00659 
00660     /* override this method to allow enumeration of your types */
00661     emd.cMediaTypes = 1;
00662     emd.pMediaTypes = This->pmt;
00663 
00664     return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
00665 }
00666 
00667 static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
00668 {
00669     Parser_OutputPin *This = (Parser_OutputPin *)iface;
00670     ParserImpl *parser = (ParserImpl *)This->pin.pin.pinInfo.pFilter;
00671 
00672     /* Set the allocator to our input pin's */
00673     EnterCriticalSection(This->pin.pin.pCritSec);
00674     This->pin.alloc = parser->pInputPin->pAlloc;
00675     LeaveCriticalSection(This->pin.pin.pCritSec);
00676 
00677     return OutputPin_Connect(iface, pReceivePin, pmt);
00678 }
00679 
00680 static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
00681 {
00682     Parser_OutputPin *This = iface;
00683 
00684     TRACE("()\n");
00685     dump_AM_MEDIA_TYPE(pmt);
00686 
00687     return (memcmp(This->pmt, pmt, sizeof(AM_MEDIA_TYPE)) == 0);
00688 }
00689 
00690 static const IPinVtbl Parser_OutputPin_Vtbl = 
00691 {
00692     Parser_OutputPin_QueryInterface,
00693     IPinImpl_AddRef,
00694     Parser_OutputPin_Release,
00695     Parser_OutputPin_Connect,
00696     OutputPin_ReceiveConnection,
00697     OutputPin_Disconnect,
00698     IPinImpl_ConnectedTo,
00699     IPinImpl_ConnectionMediaType,
00700     IPinImpl_QueryPinInfo,
00701     IPinImpl_QueryDirection,
00702     IPinImpl_QueryId,
00703     IPinImpl_QueryAccept,
00704     Parser_OutputPin_EnumMediaTypes,
00705     IPinImpl_QueryInternalConnections,
00706     OutputPin_EndOfStream,
00707     OutputPin_BeginFlush,
00708     OutputPin_EndFlush,
00709     OutputPin_NewSegment
00710 };
00711 
00712 static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface)
00713 {
00714     HRESULT hr;
00715     PullPin *This = (PullPin *)iface;
00716 
00717     TRACE("()\n");
00718 
00719     EnterCriticalSection(&This->thread_lock);
00720     EnterCriticalSection(This->pin.pCritSec);
00721     {
00722         if (This->pin.pConnectedTo)
00723         {
00724             FILTER_STATE state;
00725             ParserImpl *Parser = (ParserImpl *)This->pin.pinInfo.pFilter;
00726 
00727             LeaveCriticalSection(This->pin.pCritSec);
00728             hr = IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state);
00729             EnterCriticalSection(This->pin.pCritSec);
00730 
00731             if (SUCCEEDED(hr) && (state == State_Stopped) && SUCCEEDED(Parser->fnDisconnect(Parser)))
00732             {
00733                 LeaveCriticalSection(This->pin.pCritSec);
00734                 PullPin_Disconnect(iface);
00735                 EnterCriticalSection(This->pin.pCritSec);
00736                 hr = Parser_RemoveOutputPins((ParserImpl *)This->pin.pinInfo.pFilter);
00737             }
00738             else
00739                 hr = VFW_E_NOT_STOPPED;
00740         }
00741         else
00742             hr = S_FALSE;
00743     }
00744     LeaveCriticalSection(This->pin.pCritSec);
00745     LeaveCriticalSection(&This->thread_lock);
00746 
00747     return hr;
00748 }
00749 
00750 static HRESULT WINAPI Parser_PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
00751 {
00752     HRESULT hr;
00753 
00754     TRACE("()\n");
00755 
00756     hr = PullPin_ReceiveConnection(iface, pReceivePin, pmt);
00757     if (FAILED(hr))
00758     {
00759         IPinImpl *This = (IPinImpl *)iface;
00760 
00761         EnterCriticalSection(This->pCritSec);
00762         Parser_RemoveOutputPins((ParserImpl *)This->pinInfo.pFilter);
00763         LeaveCriticalSection(This->pCritSec);
00764     }
00765 
00766     return hr;
00767 }
00768 
00769 static const IPinVtbl Parser_InputPin_Vtbl =
00770 {
00771     PullPin_QueryInterface,
00772     IPinImpl_AddRef,
00773     PullPin_Release,
00774     InputPin_Connect,
00775     Parser_PullPin_ReceiveConnection,
00776     Parser_PullPin_Disconnect,
00777     IPinImpl_ConnectedTo,
00778     IPinImpl_ConnectionMediaType,
00779     IPinImpl_QueryPinInfo,
00780     IPinImpl_QueryDirection,
00781     IPinImpl_QueryId,
00782     IPinImpl_QueryAccept,
00783     IPinImpl_EnumMediaTypes,
00784     IPinImpl_QueryInternalConnections,
00785     PullPin_EndOfStream,
00786     PullPin_BeginFlush,
00787     PullPin_EndFlush,
00788     PullPin_NewSegment
00789 };

Generated on Mon May 28 2012 04:17:16 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.