Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
66e1ad8a
Commit
66e1ad8a
authored
Oct 05, 2010
by
Aric Stewart
Committed by
Alexandre Julliard
Oct 06, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
strmbase: Move InputPin implementation to strmbase.
parent
5c1409b5
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
640 additions
and
506 deletions
+640
-506
acmwrapper.c
dlls/quartz/acmwrapper.c
+4
-3
avidec.c
dlls/quartz/avidec.c
+4
-3
dsoundrender.c
dlls/quartz/dsoundrender.c
+19
-18
nullrenderer.c
dlls/quartz/nullrenderer.c
+17
-16
parser.c
dlls/quartz/parser.c
+1
-1
pin.c
dlls/quartz/pin.c
+1
-391
pin.h
dlls/quartz/pin.h
+0
-31
transform.c
dlls/quartz/transform.c
+17
-19
transform.h
dlls/quartz/transform.h
+7
-7
videorenderer.c
dlls/quartz/videorenderer.c
+20
-17
pin.c
dlls/strmbase/pin.c
+518
-0
strmbase.h
include/wine/strmbase.h
+32
-0
No files found.
dlls/quartz/acmwrapper.c
View file @
66e1ad8a
...
...
@@ -52,8 +52,9 @@ typedef struct ACMWrapperImpl
LONGLONG
lasttime_sent
;
}
ACMWrapperImpl
;
static
HRESULT
ACMWrapper_ProcessSampleData
(
InputPin
*
pin
,
IMediaSample
*
pSample
)
static
HRESULT
WINAPI
ACMWrapper_ProcessSampleData
(
IPin
*
iface
,
IMediaSample
*
pSample
)
{
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
ACMWrapperImpl
*
This
=
(
ACMWrapperImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
AM_MEDIA_TYPE
amt
;
IMediaSample
*
pOutSample
=
NULL
;
...
...
@@ -234,7 +235,7 @@ error:
return
hr
;
}
static
HRESULT
ACMWrapper_ConnectInput
(
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
ACMWrapper_ConnectInput
(
Base
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ACMWrapperImpl
*
This
=
(
ACMWrapperImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
MMRESULT
res
;
...
...
@@ -286,7 +287,7 @@ static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt)
return
VFW_E_TYPE_NOT_ACCEPTED
;
}
static
HRESULT
ACMWrapper_Cleanup
(
InputPin
*
pin
)
static
HRESULT
ACMWrapper_Cleanup
(
Base
InputPin
*
pin
)
{
ACMWrapperImpl
*
This
=
(
ACMWrapperImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
...
...
dlls/quartz/avidec.c
View file @
66e1ad8a
...
...
@@ -66,8 +66,9 @@ static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
return
S_OK
;
}
static
HRESULT
AVIDec_ProcessSampleData
(
InputPin
*
pin
,
IMediaSample
*
pSample
)
static
HRESULT
WINAPI
AVIDec_ProcessSampleData
(
IPin
*
iface
,
IMediaSample
*
pSample
)
{
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
AVIDecImpl
*
This
=
(
AVIDecImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
AM_MEDIA_TYPE
amt
;
HRESULT
hr
;
...
...
@@ -182,7 +183,7 @@ static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter)
return
S_OK
;
}
static
HRESULT
AVIDec_ConnectInput
(
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
AVIDec_ConnectInput
(
Base
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
AVIDecImpl
*
This
=
(
AVIDecImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
HRESULT
hr
=
VFW_E_TYPE_NOT_ACCEPTED
;
...
...
@@ -283,7 +284,7 @@ failed:
return
hr
;
}
static
HRESULT
AVIDec_Cleanup
(
InputPin
*
pin
)
static
HRESULT
AVIDec_Cleanup
(
Base
InputPin
*
pin
)
{
AVIDecImpl
*
This
=
(
AVIDecImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
...
...
dlls/quartz/dsoundrender.c
View file @
66e1ad8a
...
...
@@ -63,7 +63,7 @@ typedef struct DSoundRenderImpl
IReferenceClock
*
pClock
;
FILTER_INFO
filterInfo
;
InputPin
*
pInputPin
;
Base
InputPin
*
pInputPin
;
IDirectSound8
*
dsound
;
LPDIRECTSOUNDBUFFER
dsbuffer
;
...
...
@@ -211,9 +211,10 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *d
return
hr
;
}
static
HRESULT
DSoundRender_Sample
(
LPVOID
iface
,
IMediaSample
*
pSample
)
static
HRESULT
WINAPI
DSoundRender_Receive
(
IPin
*
iface
,
IMediaSample
*
pSample
)
{
DSoundRenderImpl
*
This
=
iface
;
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
DSoundRenderImpl
*
This
=
(
DSoundRenderImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
LPBYTE
pbSrcStream
=
NULL
;
LONG
cbSrcStream
=
0
;
REFERENCE_TIME
tStart
,
tStop
;
...
...
@@ -344,7 +345,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
return
hr
;
}
static
HRESULT
DSoundRender_QueryAccept
(
LPVOID
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
WINAPI
DSoundRender_CheckMediaType
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
WAVEFORMATEX
*
format
;
...
...
@@ -397,7 +398,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput
.
dir
=
PINDIR_INPUT
;
piInput
.
pFilter
=
(
IBaseFilter
*
)
pDSoundRender
;
lstrcpynW
(
piInput
.
achName
,
wcsInputPinName
,
sizeof
(
piInput
.
achName
)
/
sizeof
(
piInput
.
achName
[
0
]));
hr
=
InputPin_Construct
(
&
DSoundRender_InputPin_Vtbl
,
&
piInput
,
DSoundRender_Sample
,
pDSoundRender
,
DSoundRender_QueryAccept
,
NULL
,
&
pDSoundRender
->
csFilter
,
NULL
,
(
IPin
**
)
&
pDSoundRender
->
pInputPin
);
hr
=
BaseInputPin_Construct
(
&
DSoundRender_InputPin_Vtbl
,
&
piInput
,
DSoundRender_CheckMediaType
,
DSoundRender_Receive
,
&
pDSoundRender
->
csFilter
,
NULL
,
(
IPin
**
)
&
pDSoundRender
->
pInputPin
);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -809,7 +810,7 @@ static const IBaseFilterVtbl DSoundRender_Vtbl =
static
HRESULT
WINAPI
DSoundRender_InputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
PIN_DIRECTION
pindirReceive
;
DSoundRenderImpl
*
DSImpl
;
HRESULT
hr
=
S_OK
;
...
...
@@ -825,7 +826,7 @@ static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin
if
(
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_ALREADY_CONNECTED
;
if
(
SUCCEEDED
(
hr
)
&&
This
->
fn
QueryAccept
(
This
->
pUserData
,
pmt
)
!=
S_OK
)
if
(
SUCCEEDED
(
hr
)
&&
This
->
fn
CheckMediaType
(
iface
,
pmt
)
!=
S_OK
)
hr
=
VFW_E_TYPE_NOT_ACCEPTED
;
if
(
SUCCEEDED
(
hr
))
...
...
@@ -914,7 +915,7 @@ static HRESULT WINAPI DSoundRender_InputPin_Disconnect(IPin * iface)
static
HRESULT
WINAPI
DSoundRender_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
DSoundRenderImpl
*
me
=
(
DSoundRenderImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
IMediaEventSink
*
pEventSink
;
HRESULT
hr
;
...
...
@@ -922,7 +923,7 @@ static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
hr
=
InputPin
_EndOfStream
(
iface
);
hr
=
BaseInputPinImpl
_EndOfStream
(
iface
);
if
(
hr
!=
S_OK
)
{
ERR
(
"%08x
\n
"
,
hr
);
...
...
@@ -954,14 +955,14 @@ static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
static
HRESULT
WINAPI
DSoundRender_InputPin_BeginFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
DSoundRenderImpl
*
pFilter
=
(
DSoundRenderImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
HRESULT
hr
;
TRACE
(
"
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
hr
=
InputPin
_BeginFlush
(
iface
);
hr
=
BaseInputPinImpl
_BeginFlush
(
iface
);
SetEvent
(
pFilter
->
blocked
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
...
...
@@ -970,7 +971,7 @@ static HRESULT WINAPI DSoundRender_InputPin_BeginFlush(IPin * iface)
static
HRESULT
WINAPI
DSoundRender_InputPin_EndFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
DSoundRenderImpl
*
pFilter
=
(
DSoundRenderImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
HRESULT
hr
;
...
...
@@ -1002,7 +1003,7 @@ static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface)
memset
(
buffer
,
0
,
size
);
IDirectSoundBuffer_Unlock
(
pFilter
->
dsbuffer
,
buffer
,
size
,
NULL
,
0
);
}
hr
=
InputPin
_EndFlush
(
iface
);
hr
=
BaseInputPinImpl
_EndFlush
(
iface
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
MediaSeekingPassThru_ResetMediaTime
(
pFilter
->
seekthru_unk
);
...
...
@@ -1011,10 +1012,10 @@ static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface)
static
const
IPinVtbl
DSoundRender_InputPin_Vtbl
=
{
InputPin
_QueryInterface
,
BaseInputPinImpl
_QueryInterface
,
BasePinImpl_AddRef
,
InputPin
_Release
,
InputPin
_Connect
,
BaseInputPinImpl
_Release
,
BaseInputPinImpl
_Connect
,
DSoundRender_InputPin_ReceiveConnection
,
DSoundRender_InputPin_Disconnect
,
BasePinImpl_ConnectedTo
,
...
...
@@ -1022,13 +1023,13 @@ static const IPinVtbl DSoundRender_InputPin_Vtbl =
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
InputPin
_QueryAccept
,
BaseInputPinImpl
_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
DSoundRender_InputPin_EndOfStream
,
DSoundRender_InputPin_BeginFlush
,
DSoundRender_InputPin_EndFlush
,
InputPin
_NewSegment
BaseInputPinImpl
_NewSegment
};
/*** IUnknown methods ***/
...
...
dlls/quartz/nullrenderer.c
View file @
66e1ad8a
...
...
@@ -62,15 +62,16 @@ typedef struct NullRendererImpl
IReferenceClock
*
pClock
;
FILTER_INFO
filterInfo
;
InputPin
*
pInputPin
;
Base
InputPin
*
pInputPin
;
IUnknown
*
pUnkOuter
;
BOOL
bUnkOuterValid
;
BOOL
bAggregatable
;
}
NullRendererImpl
;
static
HRESULT
NullRenderer_Sample
(
LPVOID
iface
,
IMediaSample
*
pSample
)
static
HRESULT
WINAPI
NullRenderer_Receive
(
IPin
*
iface
,
IMediaSample
*
pSample
)
{
NullRendererImpl
*
This
=
iface
;
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
NullRendererImpl
*
This
=
((
NullRendererImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
);
HRESULT
hr
=
S_OK
;
REFERENCE_TIME
start
,
stop
;
...
...
@@ -86,7 +87,7 @@ static HRESULT NullRenderer_Sample(LPVOID iface, IMediaSample * pSample)
return
hr
;
}
static
HRESULT
NullRenderer_QueryAccept
(
LPVOID
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
WINAPI
NullRenderer_CheckMediaType
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
TRACE
(
"Not a stub!
\n
"
);
return
S_OK
;
...
...
@@ -121,7 +122,7 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput
.
pFilter
=
(
IBaseFilter
*
)
pNullRenderer
;
lstrcpynW
(
piInput
.
achName
,
wcsInputPinName
,
sizeof
(
piInput
.
achName
)
/
sizeof
(
piInput
.
achName
[
0
]));
hr
=
InputPin_Construct
(
&
NullRenderer_InputPin_Vtbl
,
&
piInput
,
NullRenderer_Sample
,
(
LPVOID
)
pNullRenderer
,
NullRenderer_QueryAccept
,
NULL
,
&
pNullRenderer
->
csFilter
,
NULL
,
(
IPin
**
)
&
pNullRenderer
->
pInputPin
);
hr
=
BaseInputPin_Construct
(
&
NullRenderer_InputPin_Vtbl
,
&
piInput
,
NullRenderer_CheckMediaType
,
NullRenderer_Receive
,
&
pNullRenderer
->
csFilter
,
NULL
,
(
IPin
**
)
&
pNullRenderer
->
pInputPin
);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -511,7 +512,7 @@ static const IBaseFilterVtbl NullRenderer_Vtbl =
static
HRESULT
WINAPI
NullRenderer_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
IMediaEventSink
*
pEventSink
;
NullRendererImpl
*
pNull
;
IFilterGraph
*
graph
;
...
...
@@ -519,7 +520,7 @@ static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
InputPin
_EndOfStream
(
iface
);
BaseInputPinImpl
_EndOfStream
(
iface
);
pNull
=
(
NullRendererImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
graph
=
pNull
->
filterInfo
.
pGraph
;
if
(
graph
)
...
...
@@ -538,13 +539,13 @@ static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
static
HRESULT
WINAPI
NullRenderer_InputPin_EndFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
NullRendererImpl
*
pNull
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
hr
=
InputPin
_EndOfStream
(
iface
);
hr
=
BaseInputPinImpl
_EndOfStream
(
iface
);
pNull
=
(
NullRendererImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
MediaSeekingPassThru_ResetMediaTime
(
pNull
->
seekthru_unk
);
return
hr
;
...
...
@@ -552,22 +553,22 @@ static HRESULT WINAPI NullRenderer_InputPin_EndFlush(IPin * iface)
static
const
IPinVtbl
NullRenderer_InputPin_Vtbl
=
{
InputPin
_QueryInterface
,
BaseInputPinImpl
_QueryInterface
,
BasePinImpl_AddRef
,
InputPin
_Release
,
InputPin
_Connect
,
InputPin
_ReceiveConnection
,
BaseInputPinImpl
_Release
,
BaseInputPinImpl
_Connect
,
BaseInputPinImpl
_ReceiveConnection
,
BasePinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
InputPin
_QueryAccept
,
BaseInputPinImpl
_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
NullRenderer_InputPin_EndOfStream
,
InputPin
_BeginFlush
,
BaseInputPinImpl
_BeginFlush
,
NullRenderer_InputPin_EndFlush
,
InputPin
_NewSegment
BaseInputPinImpl
_NewSegment
};
dlls/quartz/parser.c
View file @
66e1ad8a
...
...
@@ -781,7 +781,7 @@ static const IPinVtbl Parser_InputPin_Vtbl =
PullPin_QueryInterface
,
BasePinImpl_AddRef
,
PullPin_Release
,
InputPin
_Connect
,
BaseInputPinImpl
_Connect
,
Parser_PullPin_ReceiveConnection
,
Parser_PullPin_Disconnect
,
BasePinImpl_ConnectedTo
,
...
...
dlls/quartz/pin.c
View file @
66e1ad8a
...
...
@@ -29,8 +29,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
quartz
);
static
const
IPinVtbl
InputPin_Vtbl
;
static
const
IMemInputPinVtbl
MemInputPin_Vtbl
;
static
const
IPinVtbl
PullPin_Vtbl
;
#define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary))
...
...
@@ -153,184 +151,21 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
pDest
->
pFilter
=
pSrc
->
pFilter
;
}
/*** IPin implementation for an input pin ***/
HRESULT
WINAPI
InputPin_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
TRACE
(
"(%p)->(%s, %p)
\n
"
,
iface
,
qzdebugstr_guid
(
riid
),
ppv
);
*
ppv
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
))
*
ppv
=
iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IPin
))
*
ppv
=
iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IMemInputPin
))
*
ppv
=
&
This
->
lpVtblMemInput
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IMediaSeeking
))
{
return
IBaseFilter_QueryInterface
(
This
->
pin
.
pinInfo
.
pFilter
,
&
IID_IMediaSeeking
,
ppv
);
}
if
(
*
ppv
)
{
IUnknown_AddRef
((
IUnknown
*
)(
*
ppv
));
return
S_OK
;
}
FIXME
(
"No interface for %s!
\n
"
,
qzdebugstr_guid
(
riid
));
return
E_NOINTERFACE
;
}
ULONG
WINAPI
InputPin_Release
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
pin
.
refCount
);
TRACE
(
"(%p)->() Release from %d
\n
"
,
iface
,
refCount
+
1
);
if
(
!
refCount
)
{
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
if
(
This
->
pAllocator
)
IMemAllocator_Release
(
This
->
pAllocator
);
This
->
pAllocator
=
NULL
;
This
->
pin
.
lpVtbl
=
NULL
;
CoTaskMemFree
(
This
);
return
0
;
}
else
return
refCount
;
}
HRESULT
WINAPI
InputPin_Connect
(
IPin
*
iface
,
IPin
*
pConnector
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ERR
(
"Outgoing connection on an input pin! (%p, %p)
\n
"
,
pConnector
,
pmt
);
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
InputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
PIN_DIRECTION
pindirReceive
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_ALREADY_CONNECTED
;
if
(
SUCCEEDED
(
hr
)
&&
This
->
fnQueryAccept
(
This
->
pUserData
,
pmt
)
!=
S_OK
)
hr
=
VFW_E_TYPE_NOT_ACCEPTED
;
/* FIXME: shouldn't we just map common errors onto
* VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */
if
(
SUCCEEDED
(
hr
))
{
IPin_QueryDirection
(
pReceivePin
,
&
pindirReceive
);
if
(
pindirReceive
!=
PINDIR_OUTPUT
)
{
ERR
(
"Can't connect from non-output pin
\n
"
);
hr
=
VFW_E_INVALID_DIRECTION
;
}
}
if
(
SUCCEEDED
(
hr
))
{
CopyMediaType
(
&
This
->
pin
.
mtCurrent
,
pmt
);
This
->
pin
.
pConnectedTo
=
pReceivePin
;
IPin_AddRef
(
pReceivePin
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
static
HRESULT
deliver_endofstream
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_EndOfStream
(
pin
);
}
HRESULT
WINAPI
InputPin_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
pmt
);
return
(
This
->
fnQueryAccept
(
This
->
pUserData
,
pmt
)
==
S_OK
?
S_OK
:
S_FALSE
);
}
HRESULT
WINAPI
InputPin_EndOfStream
(
IPin
*
iface
)
{
HRESULT
hr
=
S_OK
;
InputPin
*
This
=
(
InputPin
*
)
iface
;
TRACE
(
"(%p)
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
This
->
flushing
)
hr
=
S_FALSE
;
else
This
->
end_of_stream
=
1
;
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
hr
==
S_OK
)
hr
=
SendFurther
(
iface
,
deliver_endofstream
,
NULL
,
NULL
);
return
hr
;
}
static
HRESULT
deliver_beginflush
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_BeginFlush
(
pin
);
}
HRESULT
WINAPI
InputPin_BeginFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
HRESULT
hr
;
TRACE
(
"() semi-stub
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
This
->
flushing
=
1
;
if
(
This
->
fnCleanProc
)
This
->
fnCleanProc
(
This
->
pUserData
);
hr
=
SendFurther
(
iface
,
deliver_beginflush
,
NULL
,
NULL
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
static
HRESULT
deliver_endflush
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_EndFlush
(
pin
);
}
HRESULT
WINAPI
InputPin_EndFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
HRESULT
hr
;
TRACE
(
"(%p)
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
This
->
flushing
=
This
->
end_of_stream
=
0
;
hr
=
SendFurther
(
iface
,
deliver_endflush
,
NULL
,
NULL
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
typedef
struct
newsegmentargs
{
REFERENCE_TIME
tStart
,
tStop
;
...
...
@@ -343,172 +178,6 @@ static HRESULT deliver_newsegment(IPin *pin, LPVOID data)
return
IPin_NewSegment
(
pin
,
args
->
tStart
,
args
->
tStop
,
args
->
rate
);
}
HRESULT
WINAPI
InputPin_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
newsegmentargs
args
;
TRACE
(
"(%x%08x, %x%08x, %e)
\n
"
,
(
ULONG
)(
tStart
>>
32
),
(
ULONG
)
tStart
,
(
ULONG
)(
tStop
>>
32
),
(
ULONG
)
tStop
,
dRate
);
args
.
tStart
=
This
->
tStart
=
tStart
;
args
.
tStop
=
This
->
tStop
=
tStop
;
args
.
rate
=
This
->
dRate
=
dRate
;
return
SendFurther
(
iface
,
deliver_newsegment
,
&
args
,
NULL
);
}
static
const
IPinVtbl
InputPin_Vtbl
=
{
InputPin_QueryInterface
,
BasePinImpl_AddRef
,
InputPin_Release
,
InputPin_Connect
,
InputPin_ReceiveConnection
,
BasePinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
InputPin_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
InputPin_EndOfStream
,
InputPin_BeginFlush
,
InputPin_EndFlush
,
InputPin_NewSegment
};
/*** IMemInputPin implementation ***/
static
inline
InputPin
*
impl_from_IMemInputPin
(
IMemInputPin
*
iface
)
{
return
(
InputPin
*
)((
char
*
)
iface
-
FIELD_OFFSET
(
InputPin
,
lpVtblMemInput
));
}
static
HRESULT
WINAPI
MemInputPin_QueryInterface
(
IMemInputPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_QueryInterface
((
IPin
*
)
&
This
->
pin
,
riid
,
ppv
);
}
static
ULONG
WINAPI
MemInputPin_AddRef
(
IMemInputPin
*
iface
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_AddRef
((
IPin
*
)
&
This
->
pin
);
}
static
ULONG
WINAPI
MemInputPin_Release
(
IMemInputPin
*
iface
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_Release
((
IPin
*
)
&
This
->
pin
);
}
static
HRESULT
WINAPI
MemInputPin_GetAllocator
(
IMemInputPin
*
iface
,
IMemAllocator
**
ppAllocator
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
ppAllocator
);
*
ppAllocator
=
This
->
pAllocator
;
if
(
*
ppAllocator
)
IMemAllocator_AddRef
(
*
ppAllocator
);
return
*
ppAllocator
?
S_OK
:
VFW_E_NO_ALLOCATOR
;
}
static
HRESULT
WINAPI
MemInputPin_NotifyAllocator
(
IMemInputPin
*
iface
,
IMemAllocator
*
pAllocator
,
BOOL
bReadOnly
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p, %d)
\n
"
,
This
,
iface
,
pAllocator
,
bReadOnly
);
if
(
bReadOnly
)
FIXME
(
"Read only flag not handled yet!
\n
"
);
/* FIXME: Should we release the allocator on disconnection? */
if
(
!
pAllocator
)
{
WARN
(
"Null allocator
\n
"
);
return
E_POINTER
;
}
if
(
This
->
preferred_allocator
&&
pAllocator
!=
This
->
preferred_allocator
)
return
E_FAIL
;
if
(
This
->
pAllocator
)
IMemAllocator_Release
(
This
->
pAllocator
);
This
->
pAllocator
=
pAllocator
;
if
(
This
->
pAllocator
)
IMemAllocator_AddRef
(
This
->
pAllocator
);
return
S_OK
;
}
static
HRESULT
WINAPI
MemInputPin_GetAllocatorRequirements
(
IMemInputPin
*
iface
,
ALLOCATOR_PROPERTIES
*
pProps
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
pProps
);
/* override this method if you have any specific requirements */
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
MemInputPin_Receive
(
IMemInputPin
*
iface
,
IMediaSample
*
pSample
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
HRESULT
hr
;
/* this trace commented out for performance reasons */
/*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/
hr
=
This
->
fnSampleProc
(
This
->
pUserData
,
pSample
);
return
hr
;
}
static
HRESULT
WINAPI
MemInputPin_ReceiveMultiple
(
IMemInputPin
*
iface
,
IMediaSample
**
pSamples
,
LONG
nSamples
,
LONG
*
nSamplesProcessed
)
{
HRESULT
hr
=
S_OK
;
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p, %d, %p)
\n
"
,
This
,
iface
,
pSamples
,
nSamples
,
nSamplesProcessed
);
for
(
*
nSamplesProcessed
=
0
;
*
nSamplesProcessed
<
nSamples
;
(
*
nSamplesProcessed
)
++
)
{
hr
=
IMemInputPin_Receive
(
iface
,
pSamples
[
*
nSamplesProcessed
]);
if
(
hr
!=
S_OK
)
break
;
}
return
hr
;
}
static
HRESULT
WINAPI
MemInputPin_ReceiveCanBlock
(
IMemInputPin
*
iface
)
{
InputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
return
S_OK
;
}
static
const
IMemInputPinVtbl
MemInputPin_Vtbl
=
{
MemInputPin_QueryInterface
,
MemInputPin_AddRef
,
MemInputPin_Release
,
MemInputPin_GetAllocator
,
MemInputPin_NotifyAllocator
,
MemInputPin_GetAllocatorRequirements
,
MemInputPin_Receive
,
MemInputPin_ReceiveMultiple
,
MemInputPin_ReceiveCanBlock
};
/*** PullPin implementation ***/
static
HRESULT
PullPin_Init
(
const
IPinVtbl
*
PullPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
SAMPLEPROC_PULL
pSampleProc
,
LPVOID
pUserData
,
...
...
@@ -1119,7 +788,7 @@ static const IPinVtbl PullPin_Vtbl =
PullPin_QueryInterface
,
BasePinImpl_AddRef
,
PullPin_Release
,
InputPin
_Connect
,
BaseInputPinImpl
_Connect
,
PullPin_ReceiveConnection
,
PullPin_Disconnect
,
BasePinImpl_ConnectedTo
,
...
...
@@ -1135,62 +804,3 @@ static const IPinVtbl PullPin_Vtbl =
PullPin_EndFlush
,
PullPin_NewSegment
};
/*** The Construct functions ***/
static
HRESULT
InputPin_Init
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
SAMPLEPROC_PUSH
pSampleProc
,
LPVOID
pUserData
,
QUERYACCEPTPROC
pQueryAccept
,
CLEANUPPROC
pCleanUp
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
allocator
,
InputPin
*
pPinImpl
)
{
TRACE
(
"
\n
"
);
/* Common attributes */
pPinImpl
->
pin
.
refCount
=
1
;
pPinImpl
->
pin
.
pConnectedTo
=
NULL
;
pPinImpl
->
pin
.
pCritSec
=
pCritSec
;
Copy_PinInfo
(
&
pPinImpl
->
pin
.
pinInfo
,
pPinInfo
);
ZeroMemory
(
&
pPinImpl
->
pin
.
mtCurrent
,
sizeof
(
AM_MEDIA_TYPE
));
/* Input pin attributes */
pPinImpl
->
pUserData
=
pUserData
;
pPinImpl
->
fnQueryAccept
=
pQueryAccept
;
pPinImpl
->
fnSampleProc
=
pSampleProc
;
pPinImpl
->
fnCleanProc
=
pCleanUp
;
pPinImpl
->
pAllocator
=
pPinImpl
->
preferred_allocator
=
allocator
;
if
(
pPinImpl
->
preferred_allocator
)
IMemAllocator_AddRef
(
pPinImpl
->
preferred_allocator
);
pPinImpl
->
tStart
=
0
;
pPinImpl
->
tStop
=
0
;
pPinImpl
->
dRate
=
1
.
0
;
pPinImpl
->
pin
.
lpVtbl
=
InputPin_Vtbl
;
pPinImpl
->
lpVtblMemInput
=
&
MemInputPin_Vtbl
;
pPinImpl
->
flushing
=
pPinImpl
->
end_of_stream
=
0
;
return
S_OK
;
}
HRESULT
InputPin_Construct
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
SAMPLEPROC_PUSH
pSampleProc
,
LPVOID
pUserData
,
QUERYACCEPTPROC
pQueryAccept
,
CLEANUPPROC
pCleanUp
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
allocator
,
IPin
**
ppPin
)
{
InputPin
*
pPinImpl
;
*
ppPin
=
NULL
;
if
(
pPinInfo
->
dir
!=
PINDIR_INPUT
)
{
ERR
(
"Pin direction(%x) != PINDIR_INPUT
\n
"
,
pPinInfo
->
dir
);
return
E_INVALIDARG
;
}
pPinImpl
=
CoTaskMemAlloc
(
sizeof
(
*
pPinImpl
));
if
(
!
pPinImpl
)
return
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
InputPin_Init
(
InputPin_Vtbl
,
pPinInfo
,
pSampleProc
,
pUserData
,
pQueryAccept
,
pCleanUp
,
pCritSec
,
allocator
,
pPinImpl
)))
{
*
ppPin
=
(
IPin
*
)
pPinImpl
;
return
S_OK
;
}
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
dlls/quartz/pin.h
View file @
66e1ad8a
...
...
@@ -24,7 +24,6 @@
* 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_PUSH
)(
LPVOID
userdata
,
IMediaSample
*
pSample
);
typedef
HRESULT
(
*
SAMPLEPROC_PULL
)(
LPVOID
userdata
,
IMediaSample
*
pSample
,
DWORD_PTR
cookie
);
/* This function will determine whether a type is supported or not.
...
...
@@ -66,24 +65,6 @@ typedef HRESULT (* STOPPROCESSPROC) (LPVOID userdata);
#define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary))
#define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary)))
typedef
struct
InputPin
{
/* inheritance C style! */
BasePin
pin
;
LPVOID
pUserData
;
const
IMemInputPinVtbl
*
lpVtblMemInput
;
IMemAllocator
*
pAllocator
;
QUERYACCEPTPROC
fnQueryAccept
;
SAMPLEPROC_PUSH
fnSampleProc
;
CLEANUPPROC
fnCleanProc
;
REFERENCE_TIME
tStart
;
REFERENCE_TIME
tStop
;
double
dRate
;
BOOL
flushing
,
end_of_stream
;
IMemAllocator
*
preferred_allocator
;
}
InputPin
;
typedef
struct
PullPin
{
/* inheritance C style! */
...
...
@@ -120,23 +101,11 @@ typedef struct PullPin
#define Req_Pause 3
/*** Constructors ***/
HRESULT
InputPin_Construct
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
SAMPLEPROC_PUSH
pSampleProc
,
LPVOID
pUserData
,
QUERYACCEPTPROC
pQueryAccept
,
CLEANUPPROC
pCleanUp
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
,
IPin
**
ppPin
);
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 ***/
/* Input Pin */
HRESULT
WINAPI
InputPin_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
);
ULONG
WINAPI
InputPin_Release
(
IPin
*
iface
);
HRESULT
WINAPI
InputPin_Connect
(
IPin
*
iface
,
IPin
*
pConnector
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
InputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
InputPin_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
InputPin_EndOfStream
(
IPin
*
iface
);
HRESULT
WINAPI
InputPin_BeginFlush
(
IPin
*
iface
);
HRESULT
WINAPI
InputPin_EndFlush
(
IPin
*
iface
);
HRESULT
WINAPI
InputPin_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
/* Pull Pin */
HRESULT
WINAPI
PullPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
PullPin_Disconnect
(
IPin
*
iface
);
...
...
dlls/quartz/transform.c
View file @
66e1ad8a
...
...
@@ -47,7 +47,7 @@ static const IBaseFilterVtbl TransformFilter_Vtbl;
static
const
IPinVtbl
TransformFilter_InputPin_Vtbl
;
static
const
IPinVtbl
TransformFilter_OutputPin_Vtbl
;
static
HRESULT
TransformFilter_Input_QueryAccept
(
LPVOID
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
WINAPI
TransformFilter_Input_CheckMediaType
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
TransformFilterImpl
*
This
=
(
TransformFilterImpl
*
)((
BasePin
*
)
iface
)
->
pinInfo
.
pFilter
;
TRACE
(
"%p
\n
"
,
iface
);
...
...
@@ -105,7 +105,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
piOutput
.
pFilter
=
(
IBaseFilter
*
)
pTransformFilter
;
lstrcpynW
(
piOutput
.
achName
,
wcsOutputPinName
,
sizeof
(
piOutput
.
achName
)
/
sizeof
(
piOutput
.
achName
[
0
]));
hr
=
InputPin_Construct
(
&
TransformFilter_InputPin_Vtbl
,
&
piInput
,
(
SAMPLEPROC_PUSH
)
pFuncsTable
->
pfnProcessSampleData
,
NULL
,
TransformFilter_Input_QueryAccept
,
NULL
,
&
pTransformFilter
->
csFilter
,
NULL
,
&
pTransformFilter
->
ppPins
[
0
]);
hr
=
BaseInputPin_Construct
(
&
TransformFilter_InputPin_Vtbl
,
&
piInput
,
TransformFilter_Input_CheckMediaType
,
pFuncsTable
->
pfnProcessSampleData
,
&
pTransformFilter
->
csFilter
,
NULL
,
&
pTransformFilter
->
ppPins
[
0
]);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -115,8 +115,6 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
props
.
cbBuffer
=
0
;
/* Will be updated at connection time */
props
.
cBuffers
=
1
;
((
InputPin
*
)
pTransformFilter
->
ppPins
[
0
])
->
pUserData
=
pTransformFilter
->
ppPins
[
0
];
hr
=
BaseOutputPin_Construct
(
&
TransformFilter_OutputPin_Vtbl
,
sizeof
(
BaseOutputPin
),
&
piOutput
,
&
props
,
NULL
,
&
pTransformFilter
->
csFilter
,
&
pTransformFilter
->
ppPins
[
1
]);
if
(
FAILED
(
hr
))
...
...
@@ -291,7 +289,7 @@ static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tS
{
if
(
This
->
state
==
State_Stopped
)
{
((
InputPin
*
)
This
->
ppPins
[
0
])
->
end_of_stream
=
0
;
((
Base
InputPin
*
)
This
->
ppPins
[
0
])
->
end_of_stream
=
0
;
if
(
This
->
pFuncsTable
->
pfnProcessBegin
)
hr
=
This
->
pFuncsTable
->
pfnProcessBegin
(
This
);
if
(
SUCCEEDED
(
hr
))
...
...
@@ -467,7 +465,7 @@ static const IBaseFilterVtbl TransformFilter_Vtbl =
static
HRESULT
WINAPI
TransformFilter_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
IPin
*
ppin
;
HRESULT
hr
;
...
...
@@ -493,7 +491,7 @@ static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
static
HRESULT
WINAPI
TransformFilter_InputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
HRESULT
hr
;
...
...
@@ -504,7 +502,7 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
hr
=
pTransform
->
pFuncsTable
->
pfnConnectInput
(
This
,
pmt
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
InputPin
_ReceiveConnection
(
iface
,
pReceivePin
,
pmt
);
hr
=
BaseInputPinImpl
_ReceiveConnection
(
iface
,
pReceivePin
,
pmt
);
if
(
FAILED
(
hr
))
pTransform
->
pFuncsTable
->
pfnCleanup
(
This
);
}
...
...
@@ -514,7 +512,7 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
static
HRESULT
WINAPI
TransformFilter_InputPin_Disconnect
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
TRACE
(
"(%p)->()
\n
"
,
iface
);
...
...
@@ -527,7 +525,7 @@ static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface)
static
HRESULT
WINAPI
TransformFilter_InputPin_BeginFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
HRESULT
hr
=
S_OK
;
...
...
@@ -538,14 +536,14 @@ static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
if
(
pTransform
->
pFuncsTable
->
pfnBeginFlush
)
hr
=
pTransform
->
pFuncsTable
->
pfnBeginFlush
(
This
);
if
(
SUCCEEDED
(
hr
))
hr
=
InputPin
_BeginFlush
(
iface
);
hr
=
BaseInputPinImpl
_BeginFlush
(
iface
);
LeaveCriticalSection
(
&
pTransform
->
csFilter
);
return
hr
;
}
static
HRESULT
WINAPI
TransformFilter_InputPin_EndFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
HRESULT
hr
=
S_OK
;
...
...
@@ -556,14 +554,14 @@ static HRESULT WINAPI TransformFilter_InputPin_EndFlush(IPin * iface)
if
(
pTransform
->
pFuncsTable
->
pfnEndFlush
)
hr
=
pTransform
->
pFuncsTable
->
pfnEndFlush
(
This
);
if
(
SUCCEEDED
(
hr
))
hr
=
InputPin
_EndFlush
(
iface
);
hr
=
BaseInputPinImpl
_EndFlush
(
iface
);
LeaveCriticalSection
(
&
pTransform
->
csFilter
);
return
hr
;
}
static
HRESULT
WINAPI
TransformFilter_InputPin_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
TransformFilterImpl
*
pTransform
;
HRESULT
hr
=
S_OK
;
...
...
@@ -574,17 +572,17 @@ static HRESULT WINAPI TransformFilter_InputPin_NewSegment(IPin * iface, REFERENC
if
(
pTransform
->
pFuncsTable
->
pfnNewSegment
)
hr
=
pTransform
->
pFuncsTable
->
pfnNewSegment
(
This
,
tStart
,
tStop
,
dRate
);
if
(
SUCCEEDED
(
hr
))
hr
=
InputPin
_NewSegment
(
iface
,
tStart
,
tStop
,
dRate
);
hr
=
BaseInputPinImpl
_NewSegment
(
iface
,
tStart
,
tStop
,
dRate
);
LeaveCriticalSection
(
&
pTransform
->
csFilter
);
return
hr
;
}
static
const
IPinVtbl
TransformFilter_InputPin_Vtbl
=
{
InputPin
_QueryInterface
,
BaseInputPinImpl
_QueryInterface
,
BasePinImpl_AddRef
,
InputPin
_Release
,
InputPin
_Connect
,
BaseInputPinImpl
_Release
,
BaseInputPinImpl
_Connect
,
TransformFilter_InputPin_ReceiveConnection
,
TransformFilter_InputPin_Disconnect
,
BasePinImpl_ConnectedTo
,
...
...
@@ -592,7 +590,7 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
InputPin
_QueryAccept
,
BaseInputPinImpl
_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
TransformFilter_InputPin_EndOfStream
,
...
...
dlls/quartz/transform.h
View file @
66e1ad8a
...
...
@@ -24,15 +24,15 @@ typedef struct TransformFilterImpl TransformFilterImpl;
typedef
struct
TransformFuncsTable
{
HRESULT
(
*
pfnProcessBegin
)
(
TransformFilterImpl
*
This
);
HRESULT
(
*
pfnProcessSampleData
)
(
InputPin
*
pin
,
IMediaSample
*
pSample
)
;
BaseInputPin_Receive
pfnProcessSampleData
;
HRESULT
(
*
pfnProcessEnd
)
(
TransformFilterImpl
*
This
);
HRESULT
(
*
pfnQueryConnect
)
(
TransformFilterImpl
*
This
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
(
*
pfnConnectInput
)
(
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
(
*
pfnCleanup
)
(
InputPin
*
pin
);
HRESULT
(
*
pfnEndOfStream
)
(
InputPin
*
pin
);
HRESULT
(
*
pfnBeginFlush
)
(
InputPin
*
pin
);
HRESULT
(
*
pfnEndFlush
)
(
InputPin
*
pin
);
HRESULT
(
*
pfnNewSegment
)
(
InputPin
*
pin
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
HRESULT
(
*
pfnConnectInput
)
(
Base
InputPin
*
pin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
(
*
pfnCleanup
)
(
Base
InputPin
*
pin
);
HRESULT
(
*
pfnEndOfStream
)
(
Base
InputPin
*
pin
);
HRESULT
(
*
pfnBeginFlush
)
(
Base
InputPin
*
pin
);
HRESULT
(
*
pfnEndFlush
)
(
Base
InputPin
*
pin
);
HRESULT
(
*
pfnNewSegment
)
(
Base
InputPin
*
pin
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
}
TransformFuncsTable
;
struct
TransformFilterImpl
...
...
dlls/quartz/videorenderer.c
View file @
66e1ad8a
...
...
@@ -68,7 +68,7 @@ typedef struct VideoRendererImpl
IReferenceClock
*
pClock
;
FILTER_INFO
filterInfo
;
InputPin
*
pInputPin
;
Base
InputPin
*
pInputPin
;
BOOL
init
;
HANDLE
hThread
;
...
...
@@ -354,9 +354,10 @@ static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data,
return
S_OK
;
}
static
HRESULT
VideoRenderer_Sample
(
LPVOID
iface
,
IMediaSample
*
pSample
)
static
HRESULT
WINAPI
VideoRenderer_Receive
(
IPin
*
iface
,
IMediaSample
*
pSample
)
{
VideoRendererImpl
*
This
=
iface
;
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
VideoRendererImpl
*
This
=
(
VideoRendererImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
LPBYTE
pbSrcStream
=
NULL
;
LONG
cbSrcStream
=
0
;
REFERENCE_TIME
tStart
,
tStop
;
...
...
@@ -491,8 +492,11 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
return
S_OK
;
}
static
HRESULT
VideoRenderer_QueryAccept
(
LPVOID
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
WINAPI
VideoRenderer_CheckMediaType
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
BaseInputPin
*
pin
=
(
BaseInputPin
*
)
iface
;
VideoRendererImpl
*
This
=
(
VideoRendererImpl
*
)
pin
->
pin
.
pinInfo
.
pFilter
;
if
(
!
IsEqualIID
(
&
pmt
->
majortype
,
&
MEDIATYPE_Video
))
return
S_FALSE
;
...
...
@@ -501,7 +505,6 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt
IsEqualIID
(
&
pmt
->
subtype
,
&
MEDIASUBTYPE_RGB565
)
||
IsEqualIID
(
&
pmt
->
subtype
,
&
MEDIASUBTYPE_RGB8
))
{
VideoRendererImpl
*
This
=
iface
;
LONG
height
;
if
(
IsEqualIID
(
&
pmt
->
formattype
,
&
FORMAT_VideoInfo
))
...
...
@@ -580,7 +583,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput
.
pFilter
=
(
IBaseFilter
*
)
pVideoRenderer
;
lstrcpynW
(
piInput
.
achName
,
wcsInputPinName
,
sizeof
(
piInput
.
achName
)
/
sizeof
(
piInput
.
achName
[
0
]));
hr
=
InputPin_Construct
(
&
VideoRenderer_InputPin_Vtbl
,
&
piInput
,
VideoRenderer_Sample
,
(
LPVOID
)
pVideoRenderer
,
VideoRenderer_QueryAccept
,
NULL
,
&
pVideoRenderer
->
csFilter
,
NULL
,
(
IPin
**
)
&
pVideoRenderer
->
pInputPin
);
hr
=
BaseInputPin_Construct
(
&
VideoRenderer_InputPin_Vtbl
,
&
piInput
,
VideoRenderer_CheckMediaType
,
VideoRenderer_Receive
,
&
pVideoRenderer
->
csFilter
,
NULL
,
(
IPin
**
)
&
pVideoRenderer
->
pInputPin
);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -1010,7 +1013,7 @@ static const IBaseFilterVtbl VideoRenderer_Vtbl =
static
HRESULT
WINAPI
VideoRenderer_InputPin_EndOfStream
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
VideoRendererImpl
*
pFilter
;
IMediaEventSink
*
pEventSink
;
HRESULT
hr
;
...
...
@@ -1031,7 +1034,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
static
HRESULT
WINAPI
VideoRenderer_InputPin_BeginFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
VideoRendererImpl
*
pVideoRenderer
=
(
VideoRendererImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
HRESULT
hr
;
...
...
@@ -1041,7 +1044,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface)
if
(
pVideoRenderer
->
state
==
State_Paused
)
SetEvent
(
pVideoRenderer
->
blocked
);
hr
=
InputPin
_BeginFlush
(
iface
);
hr
=
BaseInputPinImpl
_BeginFlush
(
iface
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
...
...
@@ -1049,7 +1052,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface)
static
HRESULT
WINAPI
VideoRenderer_InputPin_EndFlush
(
IPin
*
iface
)
{
InputPin
*
This
=
(
InputPin
*
)
iface
;
BaseInputPin
*
This
=
(
Base
InputPin
*
)
iface
;
VideoRendererImpl
*
pVideoRenderer
=
(
VideoRendererImpl
*
)
This
->
pin
.
pinInfo
.
pFilter
;
HRESULT
hr
;
...
...
@@ -1059,7 +1062,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
if
(
pVideoRenderer
->
state
==
State_Paused
)
ResetEvent
(
pVideoRenderer
->
blocked
);
hr
=
InputPin
_EndFlush
(
iface
);
hr
=
BaseInputPinImpl
_EndFlush
(
iface
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
MediaSeekingPassThru_ResetMediaTime
(
pVideoRenderer
->
seekthru_unk
);
...
...
@@ -1068,24 +1071,24 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
static
const
IPinVtbl
VideoRenderer_InputPin_Vtbl
=
{
InputPin
_QueryInterface
,
BaseInputPinImpl
_QueryInterface
,
BasePinImpl_AddRef
,
InputPin
_Release
,
InputPin
_Connect
,
InputPin
_ReceiveConnection
,
BaseInputPinImpl
_Release
,
BaseInputPinImpl
_Connect
,
BaseInputPinImpl
_ReceiveConnection
,
BasePinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
InputPin
_QueryAccept
,
BaseInputPinImpl
_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
VideoRenderer_InputPin_EndOfStream
,
VideoRenderer_InputPin_BeginFlush
,
VideoRenderer_InputPin_EndFlush
,
InputPin
_NewSegment
BaseInputPinImpl
_NewSegment
};
/*** IUnknown methods ***/
...
...
dlls/strmbase/pin.c
View file @
66e1ad8a
...
...
@@ -31,7 +31,114 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
strmbase
);
static
const
IPinVtbl
InputPin_Vtbl
;
static
const
IPinVtbl
OutputPin_Vtbl
;
static
const
IMemInputPinVtbl
MemInputPin_Vtbl
;
typedef
HRESULT
(
*
SendPinFunc
)(
IPin
*
to
,
LPVOID
arg
);
/** 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
*/
static
HRESULT
updatehres
(
HRESULT
original
,
HRESULT
new
)
{
if
(
FAILED
(
original
)
||
new
==
E_NOTIMPL
)
return
original
;
if
(
FAILED
(
new
)
||
original
==
S_OK
)
return
new
;
return
original
;
}
/** 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
*/
static
HRESULT
SendFurther
(
IPin
*
from
,
SendPinFunc
fnMiddle
,
LPVOID
arg
,
SendPinFunc
fnEnd
)
{
PIN_INFO
pin_info
;
ULONG
amount
=
0
;
HRESULT
hr
=
S_OK
;
HRESULT
hr_return
=
S_OK
;
IEnumPins
*
enumpins
=
NULL
;
BOOL
foundend
=
TRUE
;
PIN_DIRECTION
from_dir
;
IPin_QueryDirection
(
from
,
&
from_dir
);
hr
=
IPin_QueryInternalConnections
(
from
,
NULL
,
&
amount
);
if
(
hr
!=
E_NOTIMPL
&&
amount
)
FIXME
(
"Use QueryInternalConnections!
\n
"
);
hr
=
S_OK
;
pin_info
.
pFilter
=
NULL
;
hr
=
IPin_QueryPinInfo
(
from
,
&
pin_info
);
if
(
FAILED
(
hr
))
goto
out
;
hr
=
IBaseFilter_EnumPins
(
pin_info
.
pFilter
,
&
enumpins
);
if
(
FAILED
(
hr
))
goto
out
;
hr
=
IEnumPins_Reset
(
enumpins
);
while
(
hr
==
S_OK
)
{
IPin
*
pin
=
NULL
;
hr
=
IEnumPins_Next
(
enumpins
,
1
,
&
pin
,
NULL
);
if
(
hr
==
VFW_E_ENUM_OUT_OF_SYNC
)
{
hr
=
IEnumPins_Reset
(
enumpins
);
continue
;
}
if
(
pin
)
{
PIN_DIRECTION
dir
;
IPin_QueryDirection
(
pin
,
&
dir
);
if
(
dir
!=
from_dir
)
{
IPin
*
connected
=
NULL
;
foundend
=
FALSE
;
IPin_ConnectedTo
(
pin
,
&
connected
);
if
(
connected
)
{
HRESULT
hr_local
;
hr_local
=
fnMiddle
(
connected
,
arg
);
hr_return
=
updatehres
(
hr_return
,
hr_local
);
IPin_Release
(
connected
);
}
}
IPin_Release
(
pin
);
}
else
{
hr
=
S_OK
;
break
;
}
}
if
(
!
foundend
)
hr
=
hr_return
;
else
if
(
fnEnd
)
{
HRESULT
hr_local
;
hr_local
=
fnEnd
(
from
,
arg
);
hr_return
=
updatehres
(
hr_return
,
hr_local
);
}
out:
if
(
pin_info
.
pFilter
)
IBaseFilter_Release
(
pin_info
.
pFilter
);
return
hr
;
}
static
void
Copy_PinInfo
(
PIN_INFO
*
pDest
,
const
PIN_INFO
*
pSrc
)
{
...
...
@@ -758,3 +865,414 @@ HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outp
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
/*** Input Pin implementation ***/
HRESULT
WINAPI
BaseInputPinImpl_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
TRACE
(
"(%p)->(%s, %p)
\n
"
,
iface
,
debugstr_guid
(
riid
),
ppv
);
*
ppv
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
))
*
ppv
=
iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IPin
))
*
ppv
=
iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IMemInputPin
))
*
ppv
=
&
This
->
lpVtblMemInput
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IMediaSeeking
))
{
return
IBaseFilter_QueryInterface
(
This
->
pin
.
pinInfo
.
pFilter
,
&
IID_IMediaSeeking
,
ppv
);
}
if
(
*
ppv
)
{
IUnknown_AddRef
((
IUnknown
*
)(
*
ppv
));
return
S_OK
;
}
FIXME
(
"No interface for %s!
\n
"
,
debugstr_guid
(
riid
));
return
E_NOINTERFACE
;
}
ULONG
WINAPI
BaseInputPinImpl_Release
(
IPin
*
iface
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
pin
.
refCount
);
TRACE
(
"(%p)->() Release from %d
\n
"
,
iface
,
refCount
+
1
);
if
(
!
refCount
)
{
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
if
(
This
->
pAllocator
)
IMemAllocator_Release
(
This
->
pAllocator
);
This
->
pAllocator
=
NULL
;
This
->
pin
.
lpVtbl
=
NULL
;
CoTaskMemFree
(
This
);
return
0
;
}
else
return
refCount
;
}
HRESULT
WINAPI
BaseInputPinImpl_Connect
(
IPin
*
iface
,
IPin
*
pConnector
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ERR
(
"Outgoing connection on an input pin! (%p, %p)
\n
"
,
pConnector
,
pmt
);
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
BaseInputPinImpl_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
PIN_DIRECTION
pindirReceive
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_ALREADY_CONNECTED
;
if
(
SUCCEEDED
(
hr
)
&&
This
->
fnCheckMediaType
((
IPin
*
)
This
,
pmt
)
!=
S_OK
)
hr
=
VFW_E_TYPE_NOT_ACCEPTED
;
/* FIXME: shouldn't we just map common errors onto
* VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */
if
(
SUCCEEDED
(
hr
))
{
IPin_QueryDirection
(
pReceivePin
,
&
pindirReceive
);
if
(
pindirReceive
!=
PINDIR_OUTPUT
)
{
ERR
(
"Can't connect from non-output pin
\n
"
);
hr
=
VFW_E_INVALID_DIRECTION
;
}
}
if
(
SUCCEEDED
(
hr
))
{
CopyMediaType
(
&
This
->
pin
.
mtCurrent
,
pmt
);
This
->
pin
.
pConnectedTo
=
pReceivePin
;
IPin_AddRef
(
pReceivePin
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
static
HRESULT
deliver_endofstream
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_EndOfStream
(
pin
);
}
HRESULT
WINAPI
BaseInputPinImpl_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
pmt
);
return
(
This
->
fnCheckMediaType
((
IPin
*
)
This
,
pmt
)
==
S_OK
?
S_OK
:
S_FALSE
);
}
HRESULT
WINAPI
BaseInputPinImpl_EndOfStream
(
IPin
*
iface
)
{
HRESULT
hr
=
S_OK
;
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
TRACE
(
"(%p)
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
This
->
flushing
)
hr
=
S_FALSE
;
else
This
->
end_of_stream
=
1
;
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
hr
==
S_OK
)
hr
=
SendFurther
(
iface
,
deliver_endofstream
,
NULL
,
NULL
);
return
hr
;
}
static
HRESULT
deliver_beginflush
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_BeginFlush
(
pin
);
}
HRESULT
WINAPI
BaseInputPinImpl_BeginFlush
(
IPin
*
iface
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
HRESULT
hr
;
TRACE
(
"() semi-stub
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
This
->
flushing
=
1
;
hr
=
SendFurther
(
iface
,
deliver_beginflush
,
NULL
,
NULL
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
static
HRESULT
deliver_endflush
(
IPin
*
pin
,
LPVOID
unused
)
{
return
IPin_EndFlush
(
pin
);
}
HRESULT
WINAPI
BaseInputPinImpl_EndFlush
(
IPin
*
iface
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
HRESULT
hr
;
TRACE
(
"(%p)
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
This
->
flushing
=
This
->
end_of_stream
=
0
;
hr
=
SendFurther
(
iface
,
deliver_endflush
,
NULL
,
NULL
);
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
typedef
struct
newsegmentargs
{
REFERENCE_TIME
tStart
,
tStop
;
double
rate
;
}
newsegmentargs
;
static
HRESULT
deliver_newsegment
(
IPin
*
pin
,
LPVOID
data
)
{
newsegmentargs
*
args
=
data
;
return
IPin_NewSegment
(
pin
,
args
->
tStart
,
args
->
tStop
,
args
->
rate
);
}
HRESULT
WINAPI
BaseInputPinImpl_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
)
{
BaseInputPin
*
This
=
(
BaseInputPin
*
)
iface
;
newsegmentargs
args
;
TRACE
(
"(%x%08x, %x%08x, %e)
\n
"
,
(
ULONG
)(
tStart
>>
32
),
(
ULONG
)
tStart
,
(
ULONG
)(
tStop
>>
32
),
(
ULONG
)
tStop
,
dRate
);
args
.
tStart
=
This
->
tStart
=
tStart
;
args
.
tStop
=
This
->
tStop
=
tStop
;
args
.
rate
=
This
->
dRate
=
dRate
;
return
SendFurther
(
iface
,
deliver_newsegment
,
&
args
,
NULL
);
}
static
const
IPinVtbl
InputPin_Vtbl
=
{
BaseInputPinImpl_QueryInterface
,
BasePinImpl_AddRef
,
BaseInputPinImpl_Release
,
BaseInputPinImpl_Connect
,
BaseInputPinImpl_ReceiveConnection
,
BasePinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
BaseInputPinImpl_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
BaseInputPinImpl_EndOfStream
,
BaseInputPinImpl_BeginFlush
,
BaseInputPinImpl_EndFlush
,
BaseInputPinImpl_NewSegment
};
/*** IMemInputPin implementation ***/
static
inline
BaseInputPin
*
impl_from_IMemInputPin
(
IMemInputPin
*
iface
)
{
return
(
BaseInputPin
*
)((
char
*
)
iface
-
FIELD_OFFSET
(
BaseInputPin
,
lpVtblMemInput
));
}
static
HRESULT
WINAPI
MemInputPin_QueryInterface
(
IMemInputPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_QueryInterface
((
IPin
*
)
&
This
->
pin
,
riid
,
ppv
);
}
static
ULONG
WINAPI
MemInputPin_AddRef
(
IMemInputPin
*
iface
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_AddRef
((
IPin
*
)
&
This
->
pin
);
}
static
ULONG
WINAPI
MemInputPin_Release
(
IMemInputPin
*
iface
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
return
IPin_Release
((
IPin
*
)
&
This
->
pin
);
}
static
HRESULT
WINAPI
MemInputPin_GetAllocator
(
IMemInputPin
*
iface
,
IMemAllocator
**
ppAllocator
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
ppAllocator
);
*
ppAllocator
=
This
->
pAllocator
;
if
(
*
ppAllocator
)
IMemAllocator_AddRef
(
*
ppAllocator
);
return
*
ppAllocator
?
S_OK
:
VFW_E_NO_ALLOCATOR
;
}
static
HRESULT
WINAPI
MemInputPin_NotifyAllocator
(
IMemInputPin
*
iface
,
IMemAllocator
*
pAllocator
,
BOOL
bReadOnly
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p, %d)
\n
"
,
This
,
iface
,
pAllocator
,
bReadOnly
);
if
(
bReadOnly
)
FIXME
(
"Read only flag not handled yet!
\n
"
);
/* FIXME: Should we release the allocator on disconnection? */
if
(
!
pAllocator
)
{
WARN
(
"Null allocator
\n
"
);
return
E_POINTER
;
}
if
(
This
->
preferred_allocator
&&
pAllocator
!=
This
->
preferred_allocator
)
return
E_FAIL
;
if
(
This
->
pAllocator
)
IMemAllocator_Release
(
This
->
pAllocator
);
This
->
pAllocator
=
pAllocator
;
if
(
This
->
pAllocator
)
IMemAllocator_AddRef
(
This
->
pAllocator
);
return
S_OK
;
}
static
HRESULT
WINAPI
MemInputPin_GetAllocatorRequirements
(
IMemInputPin
*
iface
,
ALLOCATOR_PROPERTIES
*
pProps
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p)
\n
"
,
This
,
iface
,
pProps
);
/* override this method if you have any specific requirements */
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
MemInputPin_Receive
(
IMemInputPin
*
iface
,
IMediaSample
*
pSample
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
HRESULT
hr
;
/* this trace commented out for performance reasons */
/*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/
hr
=
This
->
fnReceive
((
IPin
*
)
This
,
pSample
);
return
hr
;
}
static
HRESULT
WINAPI
MemInputPin_ReceiveMultiple
(
IMemInputPin
*
iface
,
IMediaSample
**
pSamples
,
LONG
nSamples
,
LONG
*
nSamplesProcessed
)
{
HRESULT
hr
=
S_OK
;
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->(%p, %d, %p)
\n
"
,
This
,
iface
,
pSamples
,
nSamples
,
nSamplesProcessed
);
for
(
*
nSamplesProcessed
=
0
;
*
nSamplesProcessed
<
nSamples
;
(
*
nSamplesProcessed
)
++
)
{
hr
=
IMemInputPin_Receive
(
iface
,
pSamples
[
*
nSamplesProcessed
]);
if
(
hr
!=
S_OK
)
break
;
}
return
hr
;
}
static
HRESULT
WINAPI
MemInputPin_ReceiveCanBlock
(
IMemInputPin
*
iface
)
{
BaseInputPin
*
This
=
impl_from_IMemInputPin
(
iface
);
TRACE
(
"(%p/%p)->()
\n
"
,
This
,
iface
);
return
S_OK
;
}
static
const
IMemInputPinVtbl
MemInputPin_Vtbl
=
{
MemInputPin_QueryInterface
,
MemInputPin_AddRef
,
MemInputPin_Release
,
MemInputPin_GetAllocator
,
MemInputPin_NotifyAllocator
,
MemInputPin_GetAllocatorRequirements
,
MemInputPin_Receive
,
MemInputPin_ReceiveMultiple
,
MemInputPin_ReceiveCanBlock
};
static
HRESULT
InputPin_Init
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
BasePin_CheckMediaType
pCheckMediaType
,
BaseInputPin_Receive
pReceive
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
allocator
,
BaseInputPin
*
pPinImpl
)
{
TRACE
(
"
\n
"
);
/* Common attributes */
pPinImpl
->
pin
.
refCount
=
1
;
pPinImpl
->
pin
.
pConnectedTo
=
NULL
;
pPinImpl
->
pin
.
pCritSec
=
pCritSec
;
Copy_PinInfo
(
&
pPinImpl
->
pin
.
pinInfo
,
pPinInfo
);
ZeroMemory
(
&
pPinImpl
->
pin
.
mtCurrent
,
sizeof
(
AM_MEDIA_TYPE
));
/* Input pin attributes */
pPinImpl
->
fnCheckMediaType
=
pCheckMediaType
;
pPinImpl
->
fnReceive
=
pReceive
;
pPinImpl
->
pAllocator
=
pPinImpl
->
preferred_allocator
=
allocator
;
if
(
pPinImpl
->
preferred_allocator
)
IMemAllocator_AddRef
(
pPinImpl
->
preferred_allocator
);
pPinImpl
->
tStart
=
0
;
pPinImpl
->
tStop
=
0
;
pPinImpl
->
dRate
=
1
.
0
;
pPinImpl
->
pin
.
lpVtbl
=
InputPin_Vtbl
;
pPinImpl
->
lpVtblMemInput
=
&
MemInputPin_Vtbl
;
pPinImpl
->
flushing
=
pPinImpl
->
end_of_stream
=
0
;
return
S_OK
;
}
HRESULT
BaseInputPin_Construct
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
BasePin_CheckMediaType
pCheckMediaType
,
BaseInputPin_Receive
pReceive
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
allocator
,
IPin
**
ppPin
)
{
BaseInputPin
*
pPinImpl
;
*
ppPin
=
NULL
;
if
(
pPinInfo
->
dir
!=
PINDIR_INPUT
)
{
ERR
(
"Pin direction(%x) != PINDIR_INPUT
\n
"
,
pPinInfo
->
dir
);
return
E_INVALIDARG
;
}
pPinImpl
=
CoTaskMemAlloc
(
sizeof
(
*
pPinImpl
));
if
(
!
pPinImpl
)
return
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
InputPin_Init
(
InputPin_Vtbl
,
pPinInfo
,
pCheckMediaType
,
pReceive
,
pCritSec
,
allocator
,
pPinImpl
)))
{
*
ppPin
=
(
IPin
*
)
pPinImpl
;
return
S_OK
;
}
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
include/wine/strmbase.h
View file @
66e1ad8a
...
...
@@ -27,11 +27,14 @@ void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType);
typedef
HRESULT
(
WINAPI
*
BasePin_GetMediaType
)(
IPin
*
iface
,
int
iPosition
,
AM_MEDIA_TYPE
*
amt
);
typedef
LONG
(
WINAPI
*
BasePin_GetMediaTypeVersion
)(
IPin
*
iface
);
typedef
HRESULT
(
WINAPI
*
BasePin_AttemptConnection
)(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
typedef
HRESULT
(
WINAPI
*
BasePin_CheckMediaType
)(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
);
typedef
IPin
*
(
WINAPI
*
BaseFilter_GetPin
)(
IBaseFilter
*
iface
,
int
iPosition
);
typedef
LONG
(
WINAPI
*
BaseFilter_GetPinCount
)(
IBaseFilter
*
iface
);
typedef
LONG
(
WINAPI
*
BaseFilter_GetPinVersion
)(
IBaseFilter
*
iface
);
typedef
HRESULT
(
WINAPI
*
BaseInputPin_Receive
)(
IPin
*
This
,
IMediaSample
*
pSample
);
HRESULT
WINAPI
EnumMediaTypes_Construct
(
IPin
*
iface
,
BasePin_GetMediaType
enumFunc
,
BasePin_GetMediaTypeVersion
versionFunc
,
IEnumMediaTypes
**
ppEnum
);
HRESULT
WINAPI
EnumPins_Construct
(
IBaseFilter
*
base
,
BaseFilter_GetPin
receive_pin
,
BaseFilter_GetPinCount
receive_pincount
,
BaseFilter_GetPinVersion
receive_version
,
IEnumPins
**
ppEnum
);
...
...
@@ -61,6 +64,22 @@ typedef struct BaseOutputPin
ALLOCATOR_PROPERTIES
allocProps
;
}
BaseOutputPin
;
typedef
struct
BaseInputPin
{
/* inheritance C style! */
BasePin
pin
;
const
IMemInputPinVtbl
*
lpVtblMemInput
;
IMemAllocator
*
pAllocator
;
BaseInputPin_Receive
fnReceive
;
BasePin_CheckMediaType
fnCheckMediaType
;
REFERENCE_TIME
tStart
;
REFERENCE_TIME
tStop
;
double
dRate
;
BOOL
flushing
,
end_of_stream
;
IMemAllocator
*
preferred_allocator
;
}
BaseInputPin
;
/* Base Pin */
HRESULT
WINAPI
BasePinImpl_GetMediaType
(
IPin
*
iface
,
int
iPosition
,
AM_MEDIA_TYPE
*
pmt
);
LONG
WINAPI
BasePinImpl_GetMediaTypeVersion
(
IPin
*
iface
);
...
...
@@ -92,3 +111,16 @@ HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin * This);
HRESULT
WINAPI
BaseOutputPinImpl_Active
(
BaseOutputPin
*
This
);
HRESULT
WINAPI
BaseOutputPinImpl_Inactive
(
BaseOutputPin
*
This
);
HRESULT
WINAPI
BaseOutputPin_Construct
(
const
IPinVtbl
*
OutputPin_Vtbl
,
LONG
outputpin_size
,
const
PIN_INFO
*
pPinInfo
,
ALLOCATOR_PROPERTIES
*
props
,
BasePin_AttemptConnection
pConnectProc
,
LPCRITICAL_SECTION
pCritSec
,
IPin
**
ppPin
);
/* Base Input Pin */
HRESULT
WINAPI
BaseInputPinImpl_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
);
ULONG
WINAPI
BaseInputPinImpl_Release
(
IPin
*
iface
);
HRESULT
WINAPI
BaseInputPinImpl_Connect
(
IPin
*
iface
,
IPin
*
pConnector
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BaseInputPinImpl_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BaseInputPinImpl_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BaseInputPinImpl_EndOfStream
(
IPin
*
iface
);
HRESULT
WINAPI
BaseInputPinImpl_BeginFlush
(
IPin
*
iface
);
HRESULT
WINAPI
BaseInputPinImpl_EndFlush
(
IPin
*
iface
);
HRESULT
WINAPI
BaseInputPinImpl_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
HRESULT
BaseInputPin_Construct
(
const
IPinVtbl
*
InputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
BasePin_CheckMediaType
pQueryAccept
,
BaseInputPin_Receive
pSampleProc
,
LPCRITICAL_SECTION
pCritSec
,
IMemAllocator
*
,
IPin
**
ppPin
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment