| /* |
| * IPin function declarations to allow inheritance |
| * |
| * Copyright 2003 Robert Shearman |
| * |
| * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| /* This function will process incoming samples to the pin. |
| * Any return value valid in IMemInputPin::Receive is allowed here |
| * |
| * Cookie is the cookie that was set when requesting the buffer, if you don't |
| * implement custom requesting, you can safely ignore this |
| */ |
| typedef HRESULT (* SAMPLEPROC_PULL)(LPVOID userdata, IMediaSample * pSample, DWORD_PTR cookie); |
| |
| /* This function will determine whether a type is supported or not. |
| * It is allowed to return any error value (within reason), as opposed |
| * to IPin::QueryAccept which is only allowed to return S_OK or S_FALSE. |
| */ |
| typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt); |
| |
| /* This function is called prior to finalizing a connection with |
| * another pin and can be used to get things from the other pin |
| * like IMemInput interfaces. |
| * |
| * props contains some defaults, but you can safely override them to your liking |
| */ |
| typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props); |
| |
| /* This function is called whenever a cleanup operation has to occur, |
| * this is usually after a flush, seek, or end of stream notification. |
| * This code may even be repeated multiple times, so build your code to |
| * tolerate this behavior. Return value is ignored and should be S_OK. |
| */ |
| typedef HRESULT (* CLEANUPPROC) (LPVOID userdata); |
| |
| /* This function is called whenever a request for a new sample is made, |
| * If you implement it (it can be NULL for default behavior), you have to |
| * call IMemAllocator_GetBuffer and IMemAllocator_RequestBuffer |
| * This is useful if you want to request more than 1 buffer at simultaneously |
| * |
| * This will also cause the Sample Proc to be called with empty buffers to indicate |
| * failure in retrieving the sample. |
| */ |
| typedef HRESULT (* REQUESTPROC) (LPVOID userdata); |
| |
| /* This function is called after processing is done (for whatever reason that is caused) |
| * This is useful if you create processing threads that need to die |
| */ |
| typedef HRESULT (* STOPPROCESSPROC) (LPVOID userdata); |
| |
| #define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary)) |
| #define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary))) |
| |
| typedef struct PullPin |
| { |
| /* inheritance C style! */ |
| BasePin pin; |
| LPVOID pUserData; |
| |
| REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop; |
| IAsyncReader * pReader; |
| IMemAllocator * prefAlloc; |
| IMemAllocator * pAlloc; |
| QUERYACCEPTPROC fnQueryAccept; |
| SAMPLEPROC_PULL fnSampleProc; |
| PRECONNECTPROC fnPreConnect; |
| REQUESTPROC fnCustomRequest; |
| CLEANUPPROC fnCleanProc; |
| STOPPROCESSPROC fnDone; |
| double dRate; |
| BOOL stop_playback; |
| DWORD cbAlign; |
| |
| /* Any code that touches the thread must hold the thread lock, |
| * lock order: thread_lock and then the filter critical section |
| * also signal thread_sleepy so the thread knows to wake up |
| */ |
| CRITICAL_SECTION thread_lock; |
| HANDLE hThread; |
| DWORD requested_state; |
| HANDLE hEventStateChanged, thread_sleepy; |
| DWORD state; |
| } PullPin; |
| |
| #define Req_Sleepy 0 |
| #define Req_Die 1 |
| #define Req_Run 2 |
| #define Req_Pause 3 |
| |
| /*** Constructors ***/ |
| HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, STOPPROCESSPROC, REQUESTPROC pCustomRequest, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); |
| |
| /**************************/ |
| /*** Pin Implementation ***/ |
| |
| /* Pull Pin */ |
| HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); |
| HRESULT WINAPI PullPin_Disconnect(IPin * iface); |
| HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); |
| ULONG WINAPI PullPin_Release(IPin * iface); |
| HRESULT WINAPI PullPin_EndOfStream(IPin * iface); |
| HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); |
| HRESULT WINAPI PullPin_BeginFlush(IPin * iface); |
| HRESULT WINAPI PullPin_EndFlush(IPin * iface); |
| HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); |
| |
| /* Thread interaction functions: Hold the thread_lock before calling them */ |
| HRESULT PullPin_StartProcessing(PullPin * This); |
| HRESULT PullPin_PauseProcessing(PullPin * This); |
| HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds); |
| |
| /* COM helpers */ |
| static inline PullPin *impl_PullPin_from_IPin( IPin *iface ) |
| { |
| return CONTAINING_RECORD(iface, PullPin, pin.IPin_iface); |
| } |