1 /*
2 * IPin function declarations to allow inheritance
3 *
4 * Copyright 2003 Robert Shearman
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #pragma once
22
23 /* This function will process incoming samples to the pin.
24 * Any return value valid in IMemInputPin::Receive is allowed here
25 *
26 * Cookie is the cookie that was set when requesting the buffer, if you don't
27 * implement custom requesting, you can safely ignore this
28 */
29 typedef HRESULT (* SAMPLEPROC_PULL)(LPVOID userdata, IMediaSample * pSample, DWORD_PTR cookie);
30
31 /* This function will determine whether a type is supported or not.
32 * It is allowed to return any error value (within reason), as opposed
33 * to IPin::QueryAccept which is only allowed to return S_OK or S_FALSE.
34 */
35 typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt);
36
37 /* This function is called prior to finalizing a connection with
38 * another pin and can be used to get things from the other pin
39 * like IMemInput interfaces.
40 *
41 * props contains some defaults, but you can safely override them to your liking
42 */
43 typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props);
44
45 /* This function is called whenever a cleanup operation has to occur,
46 * this is usually after a flush, seek, or end of stream notification.
47 * This code may even be repeated multiple times, so build your code to
48 * tolerate this behavior. Return value is ignored and should be S_OK.
49 */
50 typedef HRESULT (* CLEANUPPROC) (LPVOID userdata);
51
52 /* This function is called whenever a request for a new sample is made,
53 * If you implement it (it can be NULL for default behavior), you have to
54 * call IMemAllocator_GetBuffer and IMemAllocator_RequestBuffer
55 * This is useful if you want to request more than 1 buffer at simultaneously
56 *
57 * This will also cause the Sample Proc to be called with empty buffers to indicate
58 * failure in retrieving the sample.
59 */
60 typedef HRESULT (* REQUESTPROC) (LPVOID userdata);
61
62 /* This function is called after processing is done (for whatever reason that is caused)
63 * This is useful if you create processing threads that need to die
64 */
65 typedef HRESULT (* STOPPROCESSPROC) (LPVOID userdata);
66
67 #define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary))
68 #define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary)))
69
70 typedef struct PullPin
71 {
72 /* inheritance C style! */
73 BasePin pin;
74 LPVOID pUserData;
75
76 REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop;
77 IAsyncReader * pReader;
78 IMemAllocator * prefAlloc;
79 IMemAllocator * pAlloc;
80 QUERYACCEPTPROC fnQueryAccept;
81 SAMPLEPROC_PULL fnSampleProc;
82 PRECONNECTPROC fnPreConnect;
83 REQUESTPROC fnCustomRequest;
84 CLEANUPPROC fnCleanProc;
85 STOPPROCESSPROC fnDone;
86 double dRate;
87 BOOL stop_playback;
88 DWORD cbAlign;
89
90 /* Any code that touches the thread must hold the thread lock,
91 * lock order: thread_lock and then the filter critical section
92 * also signal thread_sleepy so the thread knows to wake up
93 */
94 CRITICAL_SECTION thread_lock;
95 HANDLE hThread;
96 DWORD requested_state;
97 HANDLE hEventStateChanged, thread_sleepy;
98 DWORD state;
99 } PullPin;
100
101 #define Req_Sleepy 0
102 #define Req_Die 1
103 #define Req_Run 2
104 #define Req_Pause 3
105
106 /*** Constructors ***/
107 HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo,
108 SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept,
109 CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone,
110 LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
111
112 /**************************/
113 /*** Pin Implementation ***/
114
115 /* Pull Pin */
116 HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
117 HRESULT WINAPI PullPin_Disconnect(IPin * iface);
118 HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
119 ULONG WINAPI PullPin_Release(IPin * iface);
120 HRESULT WINAPI PullPin_EndOfStream(IPin * iface);
121 HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt);
122 HRESULT WINAPI PullPin_BeginFlush(IPin * iface);
123 HRESULT WINAPI PullPin_EndFlush(IPin * iface);
124 HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
125
126 /* Thread interaction functions: Hold the thread_lock before calling them */
127 HRESULT PullPin_StartProcessing(PullPin * This);
128 HRESULT PullPin_PauseProcessing(PullPin * This);
129 HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds);
130
131 /* COM helpers */
impl_PullPin_from_IPin(IPin * iface)132 static inline PullPin *impl_PullPin_from_IPin( IPin *iface )
133 {
134 return CONTAINING_RECORD(iface, PullPin, pin.IPin_iface);
135 }
136