ReactOS 0.4.15-dev-7788-g1ad9096
pin.c File Reference
#include "quartz_private.h"
#include "pin.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include <assert.h>
Include dependency graph for pin.c:

Go to the source code of this file.

Classes

struct  newsegmentargs
 

Macros

#define ALIGNDOWN(value, boundary)   ((value)/(boundary)*(boundary))
 
#define ALIGNUP(value, boundary)   (ALIGNDOWN((value)+(boundary)-1, (boundary)))
 

Typedefs

typedef HRESULT(* SendPinFunc) (IPin *to, LPVOID arg)
 
typedef struct newsegmentargs newsegmentargs
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (quartz)
 
static HRESULT updatehres (HRESULT original, HRESULT new)
 
static HRESULT SendFurther (IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPinFunc fnEnd)
 
static void Copy_PinInfo (PIN_INFO *pDest, const PIN_INFO *pSrc)
 
static HRESULT deliver_endofstream (IPin *pin, LPVOID unused)
 
static HRESULT deliver_beginflush (IPin *pin, LPVOID unused)
 
static HRESULT deliver_endflush (IPin *pin, LPVOID unused)
 
static HRESULT deliver_newsegment (IPin *pin, LPVOID data)
 
static HRESULT PullPin_Init (const IPinVtbl *PullPin_Vtbl, const PIN_INFO *pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, PullPin *pPinImpl)
 
HRESULT PullPin_Construct (const IPinVtbl *PullPin_Vtbl, const PIN_INFO *pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
 
static HRESULT PullPin_InitProcessing (PullPin *This)
 
HRESULT WINAPI PullPin_ReceiveConnection (IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 
HRESULT WINAPI PullPin_QueryInterface (IPin *iface, REFIID riid, LPVOID *ppv)
 
ULONG WINAPI PullPin_Release (IPin *iface)
 
static void PullPin_Flush (PullPin *This)
 
static void PullPin_Thread_Process (PullPin *This)
 
static void PullPin_Thread_Pause (PullPin *This)
 
static void PullPin_Thread_Stop (PullPin *This)
 
static DWORD WINAPI PullPin_Thread_Main (LPVOID pv)
 
HRESULT PullPin_StartProcessing (PullPin *This)
 
HRESULT PullPin_PauseProcessing (PullPin *This)
 
static HRESULT PullPin_StopProcessing (PullPin *This)
 
HRESULT PullPin_WaitForStateChange (PullPin *This, DWORD dwMilliseconds)
 
HRESULT WINAPI PullPin_QueryAccept (IPin *iface, const AM_MEDIA_TYPE *pmt)
 
HRESULT WINAPI PullPin_EndOfStream (IPin *iface)
 
HRESULT WINAPI PullPin_BeginFlush (IPin *iface)
 
HRESULT WINAPI PullPin_EndFlush (IPin *iface)
 
HRESULT WINAPI PullPin_Disconnect (IPin *iface)
 
HRESULT WINAPI PullPin_NewSegment (IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
 

Macro Definition Documentation

◆ ALIGNDOWN

#define ALIGNDOWN (   value,
  boundary 
)    ((value)/(boundary)*(boundary))

Definition at line 32 of file pin.c.

◆ ALIGNUP

#define ALIGNUP (   value,
  boundary 
)    (ALIGNDOWN((value)+(boundary)-1, (boundary)))

Definition at line 33 of file pin.c.

Typedef Documentation

◆ newsegmentargs

◆ SendPinFunc

typedef HRESULT(* SendPinFunc) (IPin *to, LPVOID arg)

Definition at line 35 of file pin.c.

Function Documentation

◆ Copy_PinInfo()

static void Copy_PinInfo ( PIN_INFO pDest,
const PIN_INFO pSrc 
)
static

Definition at line 142 of file pin.c.

143{
144 /* Tempting to just do a memcpy, but the name field is
145 128 characters long! We will probably never exceed 10
146 most of the time, so we are better off copying
147 each field manually */
148 strcpyW(pDest->achName, pSrc->achName);
149 pDest->dir = pSrc->dir;
150 pDest->pFilter = pSrc->pFilter;
151}
#define strcpyW(d, s)
Definition: unicode.h:29

Referenced by BasePinImpl_QueryPinInfo(), InputPin_Init(), OutputPin_Init(), and PullPin_Init().

◆ deliver_beginflush()

static HRESULT deliver_beginflush ( IPin pin,
LPVOID  unused 
)
static

Definition at line 158 of file pin.c.

159{
160 return IPin_BeginFlush( pin );
161}
Definition: regsvr.c:104

Referenced by BaseInputPinImpl_BeginFlush(), and PullPin_BeginFlush().

◆ deliver_endflush()

static HRESULT deliver_endflush ( IPin pin,
LPVOID  unused 
)
static

Definition at line 163 of file pin.c.

164{
165 return IPin_EndFlush( pin );
166}

Referenced by BaseInputPinImpl_EndFlush(), and PullPin_EndFlush().

◆ deliver_endofstream()

static HRESULT deliver_endofstream ( IPin pin,
LPVOID  unused 
)
static

Definition at line 153 of file pin.c.

154{
155 return IPin_EndOfStream( pin );
156}

Referenced by BaseInputPinImpl_EndOfStream(), and PullPin_EndOfStream().

◆ deliver_newsegment()

static HRESULT deliver_newsegment ( IPin pin,
LPVOID  data 
)
static

Definition at line 174 of file pin.c.

175{
177 return IPin_NewSegment(pin, args->tStart, args->tStop, args->rate);
178}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
Definition: match.c:390

Referenced by BaseInputPinImpl_NewSegment(), and PullPin_NewSegment().

◆ PullPin_BeginFlush()

HRESULT WINAPI PullPin_BeginFlush ( IPin iface)

Definition at line 739 of file pin.c.

740{
742 TRACE("(%p)->()\n", This);
743
744 EnterCriticalSection(This->pin.pCritSec);
745 {
747 }
748 LeaveCriticalSection(This->pin.pCritSec);
749
750 EnterCriticalSection(&This->thread_lock);
751 {
752 if (This->pReader)
753 IAsyncReader_BeginFlush(This->pReader);
755
756 if (This->hThread && This->state == Req_Run)
757 {
760 }
761 }
762 LeaveCriticalSection(&This->thread_lock);
763
764 EnterCriticalSection(This->pin.pCritSec);
765 {
766 This->fnCleanProc(This->pUserData);
767 }
768 LeaveCriticalSection(This->pin.pCritSec);
769
770 return S_OK;
771}
#define NULL
Definition: types.h:112
static HRESULT deliver_beginflush(IPin *pin, LPVOID unused)
Definition: pin.c:158
static HRESULT SendFurther(IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPinFunc fnEnd)
Definition: pin.c:61
HRESULT PullPin_WaitForStateChange(PullPin *This, DWORD dwMilliseconds)
Definition: pin.c:708
HRESULT PullPin_PauseProcessing(PullPin *This)
Definition: pin.c:646
#define INFINITE
Definition: serial.h:102
#define S_OK
Definition: intsafe.h:52
#define Req_Run
Definition: pin.h:103
static PullPin * impl_PullPin_from_IPin(IPin *iface)
Definition: pin.h:132
#define TRACE(s)
Definition: solgame.cpp:4
Definition: pin.h:71
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

◆ PullPin_Construct()

HRESULT PullPin_Construct ( const IPinVtbl *  PullPin_Vtbl,
const PIN_INFO pPinInfo,
SAMPLEPROC_PULL  pSampleProc,
LPVOID  pUserData,
QUERYACCEPTPROC  pQueryAccept,
CLEANUPPROC  pCleanUp,
REQUESTPROC  pCustomRequest,
STOPPROCESSPROC  pDone,
LPCRITICAL_SECTION  pCritSec,
IPin **  ppPin 
)

Definition at line 221 of file pin.c.

225{
226 PullPin * pPinImpl;
227
228 *ppPin = NULL;
229
230 if (pPinInfo->dir != PINDIR_INPUT)
231 {
232 ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
233 return E_INVALIDARG;
234 }
235
236 pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
237
238 if (!pPinImpl)
239 return E_OUTOFMEMORY;
240
241 if (SUCCEEDED(PullPin_Init(PullPin_Vtbl, pPinInfo, pSampleProc, pUserData, pQueryAccept, pCleanUp, pCustomRequest, pDone, pCritSec, pPinImpl)))
242 {
243 *ppPin = &pPinImpl->pin.IPin_iface;
244 return S_OK;
245 }
246
247 CoTaskMemFree(pPinImpl);
248 return E_FAIL;
249}
@ PINDIR_INPUT
Definition: axcore.idl:41
#define ERR(fmt,...)
Definition: debug.h:110
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, const PIN_INFO *pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, PullPin *pPinImpl)
Definition: pin.c:182
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define SUCCEEDED(hr)
Definition: intsafe.h:50
IPin IPin_iface
Definition: strmbase.h:35
BasePin pin
Definition: pin.h:73

Referenced by Parser_Create().

◆ PullPin_Disconnect()

HRESULT WINAPI PullPin_Disconnect ( IPin iface)

Definition at line 803 of file pin.c.

804{
805 HRESULT hr;
807
808 TRACE("()\n");
809
810 EnterCriticalSection(This->pin.pCritSec);
811 {
812 if (FAILED(hr = IMemAllocator_Decommit(This->pAlloc)))
813 ERR("Allocator decommit failed with error %x. Possible memory leak\n", hr);
814
815 if (This->pin.pConnectedTo)
816 {
817 IPin_Release(This->pin.pConnectedTo);
818 This->pin.pConnectedTo = NULL;
820
821 FreeMediaType(&This->pin.mtCurrent);
822 ZeroMemory(&This->pin.mtCurrent, sizeof(This->pin.mtCurrent));
823 hr = S_OK;
824 }
825 else
826 hr = S_FALSE;
827 }
828 LeaveCriticalSection(This->pin.pCritSec);
829
831 CloseHandle(This->hThread);
832 This->hThread = NULL;
833
834 return hr;
835}
static HRESULT PullPin_StopProcessing(PullPin *This)
Definition: pin.c:689
#define CloseHandle
Definition: compat.h:739
#define FAILED(hr)
Definition: intsafe.h:51
static void FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:692
HRESULT hr
Definition: shlfolder.c:183
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define ZeroMemory
Definition: winbase.h:1712
#define S_FALSE
Definition: winerror.h:2357

Referenced by Parser_PullPin_Disconnect().

◆ PullPin_EndFlush()

HRESULT WINAPI PullPin_EndFlush ( IPin iface)

Definition at line 773 of file pin.c.

774{
776
777 TRACE("(%p)->()\n", iface);
778
779 /* Send further first: Else a race condition might terminate processing early */
780 EnterCriticalSection(This->pin.pCritSec);
782 LeaveCriticalSection(This->pin.pCritSec);
783
784 EnterCriticalSection(&This->thread_lock);
785 {
786 FILTER_STATE state;
787
788 if (This->pReader)
789 IAsyncReader_EndFlush(This->pReader);
790
791 IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state);
792
793 if (state != State_Stopped)
795
797 }
798 LeaveCriticalSection(&This->thread_lock);
799
800 return S_OK;
801}
static int state
Definition: maze.c:121
HRESULT PullPin_StartProcessing(PullPin *This)
Definition: pin.c:623
static HRESULT deliver_endflush(IPin *pin, LPVOID unused)
Definition: pin.c:163

◆ PullPin_EndOfStream()

HRESULT WINAPI PullPin_EndOfStream ( IPin iface)

Definition at line 724 of file pin.c.

725{
728
729 TRACE("(%p)->()\n", iface);
730
731 EnterCriticalSection(This->pin.pCritSec);
733 SetEvent(This->hEventStateChanged);
734 LeaveCriticalSection(This->pin.pCritSec);
735
736 return hr;
737}
static HRESULT deliver_endofstream(IPin *pin, LPVOID unused)
Definition: pin.c:153
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733

◆ PullPin_Flush()

static void PullPin_Flush ( PullPin This)
static

Definition at line 402 of file pin.c.

403{
404 IMediaSample *pSample;
405 TRACE("Flushing!\n");
406
407 if (This->pReader)
408 {
409 /* Do not allow state to change while flushing */
410 EnterCriticalSection(This->pin.pCritSec);
411
412 /* Flush outstanding samples */
413 IAsyncReader_BeginFlush(This->pReader);
414
415 for (;;)
416 {
417 DWORD_PTR dwUser;
418
419 pSample = NULL;
420 IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser);
421
422 if (!pSample)
423 break;
424
425 assert(!IMediaSample_GetActualDataLength(pSample));
426
427 IMediaSample_Release(pSample);
428 }
429
430 IAsyncReader_EndFlush(This->pReader);
431
432 LeaveCriticalSection(This->pin.pCritSec);
433 }
434}
#define assert(x)
Definition: debug.h:53
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by PullPin_Thread_Main(), and PullPin_Thread_Pause().

◆ PullPin_Init()

static HRESULT PullPin_Init ( const IPinVtbl *  PullPin_Vtbl,
const PIN_INFO pPinInfo,
SAMPLEPROC_PULL  pSampleProc,
LPVOID  pUserData,
QUERYACCEPTPROC  pQueryAccept,
CLEANUPPROC  pCleanUp,
REQUESTPROC  pCustomRequest,
STOPPROCESSPROC  pDone,
LPCRITICAL_SECTION  pCritSec,
PullPin pPinImpl 
)
static

Definition at line 182 of file pin.c.

184{
185 /* Common attributes */
186 pPinImpl->pin.IPin_iface.lpVtbl = PullPin_Vtbl;
187 pPinImpl->pin.refCount = 1;
188 pPinImpl->pin.pConnectedTo = NULL;
189 pPinImpl->pin.pCritSec = pCritSec;
190 Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo);
191 ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
192
193 /* Input pin attributes */
194 pPinImpl->pUserData = pUserData;
195 pPinImpl->fnQueryAccept = pQueryAccept;
196 pPinImpl->fnSampleProc = pSampleProc;
197 pPinImpl->fnCleanProc = pCleanUp;
198 pPinImpl->fnDone = pDone;
199 pPinImpl->fnPreConnect = NULL;
200 pPinImpl->pAlloc = NULL;
201 pPinImpl->prefAlloc = NULL;
202 pPinImpl->pReader = NULL;
203 pPinImpl->hThread = NULL;
206
207 pPinImpl->rtStart = 0;
208 pPinImpl->rtCurrent = 0;
209 pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
210 pPinImpl->dRate = 1.0;
211 pPinImpl->state = Req_Die;
212 pPinImpl->fnCustomRequest = pCustomRequest;
213 pPinImpl->stop_playback = TRUE;
214
216 pPinImpl->thread_lock.DebugInfo->Spare[0] = (DWORD_PTR)( __FILE__ ": PullPin.thread_lock");
217
218 return S_OK;
219}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void Copy_PinInfo(PIN_INFO *pDest, const PIN_INFO *pSrc)
Definition: pin.c:142
#define Req_Die
Definition: pin.h:102
IPin * pConnectedTo
Definition: strmbase.h:39
PIN_INFO pinInfo
Definition: strmbase.h:38
LPCRITICAL_SECTION pCritSec
Definition: strmbase.h:37
LONG refCount
Definition: strmbase.h:36
AM_MEDIA_TYPE mtCurrent
Definition: strmbase.h:40
REFERENCE_TIME rtStop
Definition: pin.h:76
QUERYACCEPTPROC fnQueryAccept
Definition: pin.h:80
SAMPLEPROC_PULL fnSampleProc
Definition: pin.h:81
LPVOID pUserData
Definition: pin.h:74
HANDLE hThread
Definition: pin.h:95
CRITICAL_SECTION thread_lock
Definition: pin.h:94
PRECONNECTPROC fnPreConnect
Definition: pin.h:82
double dRate
Definition: pin.h:86
IMemAllocator * pAlloc
Definition: pin.h:79
REFERENCE_TIME rtCurrent
Definition: pin.h:76
DWORD state
Definition: pin.h:98
HANDLE hEventStateChanged
Definition: pin.h:97
IAsyncReader * pReader
Definition: pin.h:77
STOPPROCESSPROC fnDone
Definition: pin.h:85
CLEANUPPROC fnCleanProc
Definition: pin.h:84
BOOL stop_playback
Definition: pin.h:87
REQUESTPROC fnCustomRequest
Definition: pin.h:83
REFERENCE_TIME rtStart
Definition: pin.h:76
HANDLE thread_sleepy
Definition: pin.h:97
IMemAllocator * prefAlloc
Definition: pin.h:78
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define DWORD_PTR
Definition: treelist.c:76
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by PullPin_Construct().

◆ PullPin_InitProcessing()

static HRESULT PullPin_InitProcessing ( PullPin This)
static

Definition at line 578 of file pin.c.

579{
580 HRESULT hr = S_OK;
581
582 TRACE("(%p)->()\n", This);
583
584 /* if we are connected */
585 if (This->pAlloc)
586 {
588
589 WaitForSingleObject(This->hEventStateChanged, INFINITE);
590 EnterCriticalSection(This->pin.pCritSec);
591
592 assert(!This->hThread);
593 assert(This->state == Req_Die);
594 assert(This->stop_playback);
595 assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT);
596 This->state = Req_Sleepy;
597
598 /* AddRef the filter to make sure it and its pins will be around
599 * as long as the thread */
600 IBaseFilter_AddRef(This->pin.pinInfo.pFilter);
601
602
604 if (!This->hThread)
605 {
607 IBaseFilter_Release(This->pin.pinInfo.pFilter);
608 }
609
610 if (SUCCEEDED(hr))
611 {
612 SetEvent(This->hEventStateChanged);
613 /* If assert fails, that means a command was not processed before the thread previously terminated */
614 }
615 LeaveCriticalSection(This->pin.pCritSec);
616 }
617
618 TRACE(" -- %x\n", hr);
619
620 return hr;
621}
#define WAIT_TIMEOUT
Definition: dderror.h:14
static DWORD WINAPI PullPin_Thread_Main(LPVOID pv)
Definition: pin.c:553
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
DWORD dwThreadId
Definition: fdebug.c:31
unsigned long DWORD
Definition: ntddk_ex.h:95
#define Req_Sleepy
Definition: pin.h:101
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

Referenced by PullPin_ReceiveConnection().

◆ PullPin_NewSegment()

HRESULT WINAPI PullPin_NewSegment ( IPin iface,
REFERENCE_TIME  tStart,
REFERENCE_TIME  tStop,
double  dRate 
)

Definition at line 837 of file pin.c.

838{
840 FIXME("(%p)->(%s, %s, %g) stub\n", iface, wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate);
841
842 args.tStart = tStart;
843 args.tStop = tStop;
844 args.rate = dRate;
845
846 return SendFurther( iface, deliver_newsegment, &args, NULL );
847}
#define FIXME(fmt,...)
Definition: debug.h:111
static HRESULT deliver_newsegment(IPin *pin, LPVOID data)
Definition: pin.c:174
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define args
Definition: format.c:66

◆ PullPin_PauseProcessing()

HRESULT PullPin_PauseProcessing ( PullPin This)

Definition at line 646 of file pin.c.

647{
648 /* if we are connected */
649 TRACE("(%p)->()\n", This);
650 if(This->pAlloc)
651 {
652 assert(This->hThread);
653
655
656 EnterCriticalSection(This->pin.pCritSec);
657
658 assert(!This->stop_playback);
659 assert(This->state == Req_Run|| This->state == Req_Sleepy);
660
661 assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT);
662
663 This->state = Req_Pause;
664 This->stop_playback = TRUE;
665 ResetEvent(This->hEventStateChanged);
666 SetEvent(This->thread_sleepy);
667
668 /* Release any outstanding samples */
669 if (This->pReader)
670 {
671 IMediaSample *pSample;
672 DWORD_PTR dwUser;
673
674 do
675 {
676 pSample = NULL;
677 IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser);
678 if (pSample)
679 IMediaSample_Release(pSample);
680 } while(pSample);
681 }
682
683 LeaveCriticalSection(This->pin.pCritSec);
684 }
685
686 return S_OK;
687}
#define Req_Pause
Definition: pin.h:104
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714

Referenced by Parser_Stop(), and PullPin_BeginFlush().

◆ PullPin_QueryAccept()

HRESULT WINAPI PullPin_QueryAccept ( IPin iface,
const AM_MEDIA_TYPE pmt 
)

Definition at line 715 of file pin.c.

716{
718
719 TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
720
721 return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE);
722}

◆ PullPin_QueryInterface()

HRESULT WINAPI PullPin_QueryInterface ( IPin iface,
REFIID  riid,
LPVOID ppv 
)

Definition at line 345 of file pin.c.

346{
348
349 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
350
351 *ppv = NULL;
352
354 *ppv = iface;
355 else if (IsEqualIID(riid, &IID_IPin))
356 *ppv = iface;
357 else if (IsEqualIID(riid, &IID_IMediaSeeking) ||
358 IsEqualIID(riid, &IID_IQualityControl))
359 {
360 return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, riid, ppv);
361 }
362
363 if (*ppv)
364 {
365 IUnknown_AddRef((IUnknown *)(*ppv));
366 return S_OK;
367 }
368
369 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
370
371 return E_NOINTERFACE;
372}
const GUID IID_IUnknown
const char * qzdebugstr_guid(const GUID *id)
Definition: main.c:279
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
const GUID IID_IPin
Definition: pincontrol.cpp:15
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:2364

Referenced by Parser_PullPin_QueryInterface().

◆ PullPin_ReceiveConnection()

HRESULT WINAPI PullPin_ReceiveConnection ( IPin iface,
IPin pReceivePin,
const AM_MEDIA_TYPE pmt 
)

Definition at line 253 of file pin.c.

254{
255 PIN_DIRECTION pindirReceive;
256 HRESULT hr = S_OK;
258
259 TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
261
262 EnterCriticalSection(This->pin.pCritSec);
263 if (!This->pin.pConnectedTo)
264 {
266
267 props.cBuffers = 3;
268 props.cbBuffer = 64 * 1024; /* 64 KB */
269 props.cbAlign = 1;
270 props.cbPrefix = 0;
271
272 if (This->fnQueryAccept(This->pUserData, pmt) != S_OK)
273 hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto
274 * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */
275
276 if (SUCCEEDED(hr))
277 {
278 IPin_QueryDirection(pReceivePin, &pindirReceive);
279
280 if (pindirReceive != PINDIR_OUTPUT)
281 {
282 ERR("Can't connect from non-output pin\n");
284 }
285 }
286
287 This->pReader = NULL;
288 This->pAlloc = NULL;
289 This->prefAlloc = NULL;
290 if (SUCCEEDED(hr))
291 {
292 hr = IPin_QueryInterface(pReceivePin, &IID_IAsyncReader, (LPVOID *)&This->pReader);
293 }
294
295 if (SUCCEEDED(hr) && This->fnPreConnect)
296 {
297 hr = This->fnPreConnect(iface, pReceivePin, &props);
298 }
299
300 /*
301 * Some custom filters (such as the one used by Fallout 3
302 * and Fallout: New Vegas) expect to be passed a non-NULL
303 * preferred allocator.
304 */
305 if (SUCCEEDED(hr))
306 {
307 hr = StdMemAllocator_create(NULL, (LPVOID *) &This->prefAlloc);
308 }
309
310 if (SUCCEEDED(hr))
311 {
312 hr = IAsyncReader_RequestAllocator(This->pReader, This->prefAlloc, &props, &This->pAlloc);
313 }
314
315 if (SUCCEEDED(hr))
316 {
317 CopyMediaType(&This->pin.mtCurrent, pmt);
318 This->pin.pConnectedTo = pReceivePin;
319 IPin_AddRef(pReceivePin);
320 hr = IMemAllocator_Commit(This->pAlloc);
321 }
322
323 if (SUCCEEDED(hr))
325
326 if (FAILED(hr))
327 {
328 if (This->pReader)
329 IAsyncReader_Release(This->pReader);
330 This->pReader = NULL;
331 if (This->prefAlloc)
332 IMemAllocator_Release(This->prefAlloc);
333 This->prefAlloc = NULL;
334 if (This->pAlloc)
335 IMemAllocator_Release(This->pAlloc);
336 This->pAlloc = NULL;
337 }
338 }
339 else
341 LeaveCriticalSection(This->pin.pCritSec);
342 return hr;
343}
enum _PinDirection PIN_DIRECTION
@ PINDIR_OUTPUT
Definition: axcore.idl:42
const GUID IID_IAsyncReader
HRESULT StdMemAllocator_create(LPUNKNOWN lpUnkOuter, LPVOID *ppv)
Definition: memallocator.c:898
static HRESULT PullPin_InitProcessing(PullPin *This)
Definition: pin.c:578
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:38
#define VFW_E_ALREADY_CONNECTED
Definition: vfwmsgs.h:43
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_INVALID_DIRECTION
Definition: vfwmsgs.h:47
static const WCHAR props[]
Definition: wbemdisp.c:288

Referenced by Parser_PullPin_ReceiveConnection().

◆ PullPin_Release()

ULONG WINAPI PullPin_Release ( IPin iface)

Definition at line 374 of file pin.c.

375{
377 ULONG refCount = InterlockedDecrement(&This->pin.refCount);
378
379 TRACE("(%p)->() Release from %d\n", This, refCount + 1);
380
381 if (!refCount)
382 {
383 WaitForSingleObject(This->hEventStateChanged, INFINITE);
384 assert(!This->hThread);
385
386 if(This->prefAlloc)
387 IMemAllocator_Release(This->prefAlloc);
388 if(This->pAlloc)
389 IMemAllocator_Release(This->pAlloc);
390 if(This->pReader)
391 IAsyncReader_Release(This->pReader);
392 CloseHandle(This->thread_sleepy);
393 CloseHandle(This->hEventStateChanged);
394 This->thread_lock.DebugInfo->Spare[0] = 0;
395 DeleteCriticalSection(&This->thread_lock);
397 return 0;
398 }
399 return refCount;
400}
#define InterlockedDecrement
Definition: armddk.h:52
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ PullPin_StartProcessing()

HRESULT PullPin_StartProcessing ( PullPin This)

Definition at line 623 of file pin.c.

624{
625 /* if we are connected */
626 TRACE("(%p)->()\n", This);
627 if(This->pAlloc)
628 {
629 assert(This->hThread);
630
632
633 assert(This->state == Req_Sleepy);
634
635 /* Wake up! */
636 assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT);
637 This->state = Req_Run;
638 This->stop_playback = FALSE;
639 ResetEvent(This->hEventStateChanged);
640 SetEvent(This->thread_sleepy);
641 }
642
643 return S_OK;
644}

Referenced by Parser_Run(), and PullPin_EndFlush().

◆ PullPin_StopProcessing()

static HRESULT PullPin_StopProcessing ( PullPin This)
static

Definition at line 689 of file pin.c.

690{
691 TRACE("(%p)->()\n", This);
692
693 /* if we are alive */
694 assert(This->hThread);
695
697
698 assert(This->state == Req_Pause || This->state == Req_Sleepy);
699
700 This->stop_playback = TRUE;
701 This->state = Req_Die;
702 assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT);
703 ResetEvent(This->hEventStateChanged);
704 SetEvent(This->thread_sleepy);
705 return S_OK;
706}

Referenced by PullPin_Disconnect().

◆ PullPin_Thread_Main()

static DWORD WINAPI PullPin_Thread_Main ( LPVOID  pv)
static

Definition at line 553 of file pin.c.

554{
555 PullPin *This = pv;
557
559
560 for (;;)
561 {
562 WaitForSingleObject(This->thread_sleepy, INFINITE);
563
564 TRACE("State: %d\n", This->state);
565
566 switch (This->state)
567 {
568 case Req_Die: PullPin_Thread_Stop(This); break;
569 case Req_Run: PullPin_Thread_Process(This); break;
570 case Req_Pause: PullPin_Thread_Pause(This); break;
571 case Req_Sleepy: ERR("Should not be signalled with SLEEPY!\n"); break;
572 default: ERR("Unknown state request: %d\n", This->state); break;
573 }
574 }
575 return 0;
576}
static void PullPin_Thread_Pause(PullPin *This)
Definition: pin.c:529
static void PullPin_Thread_Stop(PullPin *This)
Definition: pin.c:539
static void PullPin_Flush(PullPin *This)
Definition: pin.c:402
static void PullPin_Thread_Process(PullPin *This)
Definition: pin.c:436
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
@ COINIT_MULTITHREADED
Definition: objbase.h:279

Referenced by PullPin_InitProcessing().

◆ PullPin_Thread_Pause()

static void PullPin_Thread_Pause ( PullPin This)
static

Definition at line 529 of file pin.c.

530{
532
533 EnterCriticalSection(This->pin.pCritSec);
534 This->state = Req_Sleepy;
535 SetEvent(This->hEventStateChanged);
536 LeaveCriticalSection(This->pin.pCritSec);
537}

Referenced by PullPin_Thread_Main().

◆ PullPin_Thread_Process()

static void PullPin_Thread_Process ( PullPin This)
static

Definition at line 436 of file pin.c.

437{
438 HRESULT hr;
439 IMediaSample * pSample = NULL;
440 ALLOCATOR_PROPERTIES allocProps;
441
442 hr = IMemAllocator_GetProperties(This->pAlloc, &allocProps);
443
444 This->cbAlign = allocProps.cbAlign;
445
446 if (This->rtCurrent < This->rtStart)
447 This->rtCurrent = MEDIATIME_FROM_BYTES(ALIGNDOWN(BYTES_FROM_MEDIATIME(This->rtStart), This->cbAlign));
448
449 TRACE("Start\n");
450
451 if (This->rtCurrent >= This->rtStop)
452 {
453 IPin_EndOfStream(&This->pin.IPin_iface);
454 return;
455 }
456
457 /* There is no sample in our buffer */
458 hr = This->fnCustomRequest(This->pUserData);
459
460 if (FAILED(hr))
461 ERR("Request error: %x\n", hr);
462
463 EnterCriticalSection(This->pin.pCritSec);
464 SetEvent(This->hEventStateChanged);
465 LeaveCriticalSection(This->pin.pCritSec);
466
467 if (SUCCEEDED(hr))
468 do
469 {
470 DWORD_PTR dwUser;
471
472 TRACE("Process sample\n");
473
474 pSample = NULL;
475 hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser);
476
477 /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */
478 if (SUCCEEDED(hr))
479 {
480 hr = This->fnSampleProc(This->pUserData, pSample, dwUser);
481 }
482 else
483 {
484 if (hr == VFW_E_TIMEOUT)
485 {
486 if (pSample != NULL)
487 WARN("Non-NULL sample returned with VFW_E_TIMEOUT.\n");
488 hr = S_OK;
489 }
490 /* FIXME: Errors are not well handled yet! */
491 else
492 ERR("Processing error: %x\n", hr);
493 }
494
495 if (pSample)
496 {
497 IMediaSample_Release(pSample);
498 pSample = NULL;
499 }
500 } while (This->rtCurrent < This->rtStop && hr == S_OK && !This->stop_playback);
501
502 /*
503 * Sample was rejected, and we are asked to terminate. When there is more than one buffer
504 * it is possible for a filter to have several queued samples, making it necessary to
505 * release all of these pending samples.
506 */
507 if (This->stop_playback || FAILED(hr))
508 {
509 DWORD_PTR dwUser;
510
511 do
512 {
513 if (pSample)
514 IMediaSample_Release(pSample);
515 pSample = NULL;
516 IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser);
517 } while(pSample);
518 }
519
520 /* Can't reset state to Sleepy here because that might race, instead PauseProcessing will do that for us
521 * Flush remaining samples
522 */
523 if (This->fnDone)
524 This->fnDone(This->pUserData);
525
526 TRACE("End: %08x, %d\n", hr, This->stop_playback);
527}
#define WARN(fmt,...)
Definition: debug.h:112
#define ALIGNDOWN(value, boundary)
Definition: pin.c:32
#define MEDIATIME_FROM_BYTES(x)
#define BYTES_FROM_MEDIATIME(time)
#define VFW_E_TIMEOUT
Definition: vfwmsgs.h:85

Referenced by PullPin_Thread_Main().

◆ PullPin_Thread_Stop()

static void PullPin_Thread_Stop ( PullPin This)
static

Definition at line 539 of file pin.c.

540{
541 TRACE("(%p)->()\n", This);
542
543 EnterCriticalSection(This->pin.pCritSec);
544 SetEvent(This->hEventStateChanged);
545 LeaveCriticalSection(This->pin.pCritSec);
546
547 IBaseFilter_Release(This->pin.pinInfo.pFilter);
548
550 ExitThread(0);
551}
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067

Referenced by PullPin_Thread_Main().

◆ PullPin_WaitForStateChange()

HRESULT PullPin_WaitForStateChange ( PullPin This,
DWORD  dwMilliseconds 
)

Definition at line 708 of file pin.c.

709{
710 if (WaitForSingleObject(This->hEventStateChanged, dwMilliseconds) == WAIT_TIMEOUT)
711 return S_FALSE;
712 return S_OK;
713}

Referenced by Parser_Destroy(), Parser_GetState(), Parser_Stop(), PullPin_BeginFlush(), PullPin_EndFlush(), PullPin_PauseProcessing(), PullPin_StartProcessing(), and PullPin_StopProcessing().

◆ SendFurther()

static HRESULT SendFurther ( IPin from,
SendPinFunc  fnMiddle,
LPVOID  arg,
SendPinFunc  fnEnd 
)
static

Sends a message from a pin further to other, similar pins fnMiddle is called on each pin found further on the stream. fnEnd (can be NULL) is called when the message can't be sent any further (this is a renderer or source)

If the pin given is an input pin, the message will be sent downstream to other input pins If the pin given is an output pin, the message will be sent upstream to other output pins

Definition at line 61 of file pin.c.

62{
63 PIN_INFO pin_info;
64 ULONG amount = 0;
65 HRESULT hr = S_OK;
66 HRESULT hr_return = S_OK;
67 IEnumPins *enumpins = NULL;
68 BOOL foundend = TRUE;
69 PIN_DIRECTION from_dir;
70
71 IPin_QueryDirection( from, &from_dir );
72
73 hr = IPin_QueryInternalConnections( from, NULL, &amount );
74 if (hr != E_NOTIMPL && amount)
75 FIXME("Use QueryInternalConnections!\n");
76
77 pin_info.pFilter = NULL;
78 hr = IPin_QueryPinInfo( from, &pin_info );
79 if (FAILED(hr))
80 goto out;
81
82 hr = IBaseFilter_EnumPins( pin_info.pFilter, &enumpins );
83 if (FAILED(hr))
84 goto out;
85
86 hr = IEnumPins_Reset( enumpins );
87 while (hr == S_OK) {
88 IPin *pin = NULL;
89 hr = IEnumPins_Next( enumpins, 1, &pin, NULL );
91 {
92 hr = IEnumPins_Reset( enumpins );
93 continue;
94 }
95 if (pin)
96 {
98
99 IPin_QueryDirection( pin, &dir );
100 if (dir != from_dir)
101 {
103
104 foundend = FALSE;
105 IPin_ConnectedTo( pin, &connected );
106 if (connected)
107 {
108 HRESULT hr_local;
109
110 hr_local = fnMiddle( connected, arg );
111 hr_return = updatehres( hr_return, hr_local );
112 IPin_Release(connected);
113 }
114 }
115 IPin_Release( pin );
116 }
117 else
118 {
119 hr = S_OK;
120 break;
121 }
122 }
123
124 if (!foundend)
125 hr = hr_return;
126 else if (fnEnd) {
127 HRESULT hr_local;
128
129 hr_local = fnEnd( from, arg );
130 hr_return = updatehres( hr_return, hr_local );
131 }
132
133out:
134 if (enumpins)
135 IEnumPins_Release( enumpins );
136 if (pin_info.pFilter)
137 IBaseFilter_Release( pin_info.pFilter );
138 return hr;
139}
unsigned int dir
Definition: maze.c:112
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT updatehres(HRESULT original, HRESULT new)
Definition: pin.c:43
unsigned int BOOL
Definition: ntddk_ex.h:94
int connected
Definition: main.c:61
Definition: axcore.idl:92
static FILE * out
Definition: regtests2xml.c:44
CardRegion * from
Definition: spigame.cpp:19
#define VFW_E_ENUM_OUT_OF_SYNC
Definition: vfwmsgs.h:42

Referenced by BaseInputPinImpl_BeginFlush(), BaseInputPinImpl_EndFlush(), BaseInputPinImpl_EndOfStream(), BaseInputPinImpl_NewSegment(), PullPin_BeginFlush(), PullPin_EndFlush(), PullPin_EndOfStream(), and PullPin_NewSegment().

◆ updatehres()

static HRESULT updatehres ( HRESULT  original,
HRESULT  new 
)
static

Helper function, there are a lot of places where the error code is inherited The following rules apply:

Return the first received error code (E_NOTIMPL is ignored) If no errors occur: return the first received non-error-code that isn't S_OK

Definition at line 43 of file pin.c.

44{
45 if (FAILED( original ) || new == E_NOTIMPL)
46 return original;
47
48 if (FAILED( new ) || original == S_OK)
49 return new;
50
51 return original;
52}

Referenced by SendFurther().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( quartz  )