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
5c1409b5
Commit
5c1409b5
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 OutputPin implementation to strmbase.
parent
0410e50e
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
641 additions
and
1020 deletions
+641
-1020
Makefile.in
dlls/qcap/Makefile.in
+0
-1
enummedia.c
dlls/qcap/enummedia.c
+0
-15
pin.c
dlls/qcap/pin.c
+0
-314
pin.h
dlls/qcap/pin.h
+0
-58
qcap_main.h
dlls/qcap/qcap_main.h
+0
-1
v4l.c
dlls/qcap/v4l.c
+4
-5
vfwcapture.c
dlls/qcap/vfwcapture.c
+9
-15
acmwrapper.c
dlls/quartz/acmwrapper.c
+3
-3
avidec.c
dlls/quartz/avidec.c
+3
-3
avisplit.c
dlls/quartz/avisplit.c
+1
-1
enummedia.c
dlls/quartz/enummedia.c
+0
-10
filesource.c
dlls/quartz/filesource.c
+11
-12
mpegsplit.c
dlls/quartz/mpegsplit.c
+1
-1
parser.c
dlls/quartz/parser.c
+11
-11
parser.h
dlls/quartz/parser.h
+1
-1
pin.c
dlls/quartz/pin.c
+0
-526
pin.h
dlls/quartz/pin.h
+0
-31
transform.c
dlls/quartz/transform.c
+11
-11
waveparser.c
dlls/quartz/waveparser.c
+1
-1
pin.c
dlls/strmbase/pin.c
+553
-0
strmbase.h
include/wine/strmbase.h
+32
-0
No files found.
dlls/qcap/Makefile.in
View file @
5c1409b5
...
...
@@ -5,7 +5,6 @@ C_SRCS = \
capturegraph.c
\
dllsetup.c
\
enummedia.c
\
pin.c
\
qcap_main.c
\
v4l.c
\
vfwcapture.c
\
...
...
dlls/qcap/enummedia.c
View file @
5c1409b5
...
...
@@ -35,21 +35,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
qcap
);
BOOL
CompareMediaTypes
(
const
AM_MEDIA_TYPE
*
pmt1
,
const
AM_MEDIA_TYPE
*
pmt2
,
BOOL
bWildcards
)
{
TRACE
(
"pmt1: "
);
dump_AM_MEDIA_TYPE
(
pmt1
);
TRACE
(
"pmt2: "
);
dump_AM_MEDIA_TYPE
(
pmt2
);
return
(((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
majortype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
majortype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
majortype
,
&
pmt2
->
majortype
))
&&
((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
subtype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
subtype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
subtype
,
&
pmt2
->
subtype
)));
}
void
dump_AM_MEDIA_TYPE
(
const
AM_MEDIA_TYPE
*
pmt
)
{
if
(
!
pmt
)
...
...
dlls/qcap/pin.c
deleted
100644 → 0
View file @
0410e50e
/*
* Generic Implementation of IPin Interface
*
* Copyright 2003 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "wingdi.h"
#include "winuser.h"
#include "dshow.h"
#include "qcap_main.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include <assert.h>
#include "pin.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
qcap
);
#define ALIGNDOWN(value,boundary) ((value) & ~(boundary-1))
#define ALIGNUP(value,boundary) (ALIGNDOWN(value - 1, boundary) + boundary)
static
void
Copy_PinInfo
(
PIN_INFO
*
pDest
,
const
PIN_INFO
*
pSrc
)
{
/* Tempting to just do a memcpy, but the name field is
128 characters long! We will probably never exceed 10
most of the time, so we are better off copying
each field manually */
strcpyW
(
pDest
->
achName
,
pSrc
->
achName
);
pDest
->
dir
=
pSrc
->
dir
;
pDest
->
pFilter
=
pSrc
->
pFilter
;
}
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* NOTE: not part of standard interface */
static
HRESULT
OutputPin_ConnectSpecific
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
HRESULT
hr
;
IMemAllocator
*
pMemAlloc
=
NULL
;
ALLOCATOR_PROPERTIES
actual
;
/* FIXME: should we put the actual props back in to This? */
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* FIXME: call queryacceptproc */
This
->
pin
.
pConnectedTo
=
pReceivePin
;
IPin_AddRef
(
pReceivePin
);
CopyMediaType
(
&
This
->
pin
.
mtCurrent
,
pmt
);
hr
=
IPin_ReceiveConnection
(
pReceivePin
,
iface
,
pmt
);
/* get the IMemInputPin interface we will use to deliver samples to the
* connected pin */
if
(
SUCCEEDED
(
hr
))
{
hr
=
IPin_QueryInterface
(
pReceivePin
,
&
IID_IMemInputPin
,
(
LPVOID
)
&
This
->
pMemInputPin
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pMemAlloc
);
if
(
hr
==
VFW_E_NO_ALLOCATOR
)
{
/* Input pin provides no allocator, use standard memory allocator */
hr
=
CoCreateInstance
(
&
CLSID_MemoryAllocator
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_IMemAllocator
,
(
LPVOID
*
)
&
pMemAlloc
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IMemInputPin_NotifyAllocator
(
This
->
pMemInputPin
,
pMemAlloc
,
FALSE
);
}
}
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_SetProperties
(
pMemAlloc
,
&
This
->
allocProps
,
&
actual
);
if
(
pMemAlloc
)
IMemAllocator_Release
(
pMemAlloc
);
/* break connection if we couldn't get the allocator */
if
(
FAILED
(
hr
))
IPin_Disconnect
(
pReceivePin
);
}
if
(
FAILED
(
hr
))
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
DeleteMediaType
(
&
This
->
pin
.
mtCurrent
);
}
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
HRESULT
OutputPin_Init
(
const
PIN_INFO
*
pPinInfo
,
const
ALLOCATOR_PROPERTIES
*
props
,
LPCRITICAL_SECTION
pCritSec
,
OutputPin
*
pPinImpl
)
{
TRACE
(
"
\n
"
);
/* Common attributes */
pPinImpl
->
pin
.
refCount
=
1
;
pPinImpl
->
pin
.
pConnectedTo
=
NULL
;
pPinImpl
->
pin
.
pCritSec
=
pCritSec
;
Copy_PinInfo
(
&
pPinImpl
->
pin
.
pinInfo
,
pPinInfo
);
/* Output pin attributes */
pPinImpl
->
pMemInputPin
=
NULL
;
pPinImpl
->
pConnectSpecific
=
OutputPin_ConnectSpecific
;
if
(
props
)
{
pPinImpl
->
allocProps
=
*
props
;
if
(
pPinImpl
->
allocProps
.
cbAlign
==
0
)
pPinImpl
->
allocProps
.
cbAlign
=
1
;
}
else
ZeroMemory
(
&
pPinImpl
->
allocProps
,
sizeof
(
pPinImpl
->
allocProps
));
return
S_OK
;
}
HRESULT
WINAPI
OutputPin_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
HRESULT
hr
;
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%p, %p)
\n
"
,
This
,
iface
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* If we try to connect to ourself, we will definitely deadlock.
* There are other cases where we could deadlock too, but this
* catches the obvious case */
assert
(
pReceivePin
!=
iface
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
/* if we have been a specific type to connect with, then we can either connect
* with that or fail. We cannot choose different AM_MEDIA_TYPE */
if
(
pmt
&&
!
IsEqualGUID
(
&
pmt
->
majortype
,
&
GUID_NULL
)
&&
!
IsEqualGUID
(
&
pmt
->
subtype
,
&
GUID_NULL
))
hr
=
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmt
);
else
{
/* negotiate media type */
IEnumMediaTypes
*
pEnumCandidates
;
AM_MEDIA_TYPE
*
pmtCandidate
;
/* Candidate media type */
if
(
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
iface
,
&
pEnumCandidates
)))
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
/* try this filter's media types first */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
TRACE
(
"o_o
\n
"
);
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
}
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* then try receiver filter's media types */
if
(
hr
!=
S_OK
&&
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
pReceivePin
,
&
pEnumCandidates
)))
/* if we haven't already connected successfully */
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
}
/* while */
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* if not found */
}
/* if negotiate media type */
}
/* if succeeded */
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
HRESULT
WINAPI
OutputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ERR
(
"Incoming connection on an output pin! (%p, %p)
\n
"
,
pReceivePin
,
pmt
);
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
OutputPin_Disconnect
(
IPin
*
iface
)
{
HRESULT
hr
;
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
TRACE
(
"()
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
This
->
pMemInputPin
)
{
IMemInputPin_Release
(
This
->
pMemInputPin
);
This
->
pMemInputPin
=
NULL
;
}
if
(
This
->
pin
.
pConnectedTo
)
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
hr
=
S_OK
;
}
else
hr
=
S_FALSE
;
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
HRESULT
OutputPin_GetDeliveryBuffer
(
OutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
)
{
HRESULT
hr
;
TRACE
(
"(%p, %p, %p, %x)
\n
"
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_GetBuffer
(
pAlloc
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMediaSample_SetTime
(
*
ppSample
,
tStart
,
tStop
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
HRESULT
OutputPin_SendSample
(
OutputPin
*
This
,
IMediaSample
*
pSample
)
{
HRESULT
hr
=
S_OK
;
IMemInputPin
*
pMemConnected
=
NULL
;
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
/* we don't have the lock held when using This->pMemInputPin,
* so we need to AddRef it to stop it being deleted while we are
* using it. */
pMemConnected
=
This
->
pMemInputPin
;
IMemInputPin_AddRef
(
pMemConnected
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
SUCCEEDED
(
hr
))
{
/* NOTE: if we are in a critical section when Receive is called
* then it causes some problems (most notably with the native Video
* Renderer) if we are re-entered for whatever reason */
hr
=
IMemInputPin_Receive
(
pMemConnected
,
pSample
);
IMemInputPin_Release
(
pMemConnected
);
}
return
hr
;
}
dlls/qcap/pin.h
deleted
100644 → 0
View file @
0410e50e
/*
* IPin function declarations to allow inheritance
*
* Copyright 2003 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* This function will process incoming samples to the pin.
* Any return value valid in IMemInputPin::Receive is allowed here
*/
typedef
HRESULT
(
*
SAMPLEPROC
)(
LPVOID
userdata
,
IMediaSample
*
pSample
);
/* This function will determine whether a type is supported or not.
* It is allowed to return any error value (within reason), as opposed
* to IPin::QueryAccept which is only allowed to return S_OK or S_FALSE.
*/
typedef
HRESULT
(
*
QUERYACCEPTPROC
)(
LPVOID
userdata
,
const
AM_MEDIA_TYPE
*
pmt
);
/* This function is called prior to finalizing a connection with
* another pin and can be used to get things from the other pin
* like IMemInput interfaces.
*/
typedef
HRESULT
(
*
PRECONNECTPROC
)(
IPin
*
iface
,
IPin
*
pConnectPin
);
typedef
struct
OutputPin
{
/* inheritance C style! */
BasePin
pin
;
IMemInputPin
*
pMemInputPin
;
HRESULT
(
*
pConnectSpecific
)(
IPin
*
iface
,
IPin
*
pReceiver
,
const
AM_MEDIA_TYPE
*
pmt
);
ALLOCATOR_PROPERTIES
allocProps
;
}
OutputPin
;
/*** Initializers ***/
HRESULT
OutputPin_Init
(
const
PIN_INFO
*
pPinInfo
,
const
ALLOCATOR_PROPERTIES
*
props
,
LPCRITICAL_SECTION
pCritSec
,
OutputPin
*
pPinImpl
);
/* Output Pin */
HRESULT
WINAPI
OutputPin_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
OutputPin_Disconnect
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
OutputPin_GetDeliveryBuffer
(
OutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
);
HRESULT
OutputPin_SendSample
(
OutputPin
*
This
,
IMediaSample
*
pSample
);
dlls/qcap/qcap_main.h
View file @
5c1409b5
...
...
@@ -37,7 +37,6 @@ extern IUnknown * WINAPI QCAP_createInfinitePinTeeFilter(IUnknown *pUnkOuter, HR
extern
IUnknown
*
WINAPI
QCAP_createSmartTeeFilter
(
IUnknown
*
pUnkOuter
,
HRESULT
*
phr
);
extern
IUnknown
*
WINAPI
QCAP_createAudioInputMixerPropertyPage
(
IUnknown
*
pUnkOuter
,
HRESULT
*
phr
);
BOOL
CompareMediaTypes
(
const
AM_MEDIA_TYPE
*
pmt1
,
const
AM_MEDIA_TYPE
*
pmt2
,
BOOL
bWildcards
);
void
dump_AM_MEDIA_TYPE
(
const
AM_MEDIA_TYPE
*
pmt
);
enum
YUV_Format
{
...
...
dlls/qcap/v4l.c
View file @
5c1409b5
...
...
@@ -43,7 +43,6 @@
#include "capture.h"
#include "qcap_main.h"
#include "pin.h"
#include <stdio.h>
#include <fcntl.h>
...
...
@@ -619,7 +618,7 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
EnterCriticalSection
(
&
capBox
->
CritSect
);
if
(
capBox
->
stopped
)
break
;
hr
=
OutputPin_GetDeliveryBuffer
((
OutputPin
*
)
capBox
->
pOut
,
&
pSample
,
NULL
,
NULL
,
0
);
hr
=
BaseOutputPinImpl_GetDeliveryBuffer
((
Base
OutputPin
*
)
capBox
->
pOut
,
&
pSample
,
NULL
,
NULL
,
0
);
if
(
SUCCEEDED
(
hr
))
{
int
len
;
...
...
@@ -638,7 +637,7 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
V4l_GetFrame
(
capBox
,
&
pInput
);
capBox
->
renderer
(
capBox
,
pOutput
,
pInput
);
Resize
(
capBox
,
pTarget
,
pOutput
);
hr
=
OutputPin_SendSample
((
OutputPin
*
)
capBox
->
pOut
,
pSample
);
hr
=
BaseOutputPinImpl_Deliver
((
Base
OutputPin
*
)
capBox
->
pOut
,
pSample
);
TRACE
(
"%p -> Frame %u: %x
\n
"
,
capBox
,
++
framecount
,
hr
);
IMediaSample_Release
(
pSample
);
V4l_FreeFrame
(
capBox
);
...
...
@@ -686,7 +685,7 @@ HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
{
IMemAllocator
*
pAlloc
=
NULL
;
ALLOCATOR_PROPERTIES
ap
,
actual
;
OutputPin
*
out
;
Base
OutputPin
*
out
;
ap
.
cBuffers
=
3
;
if
(
!
capBox
->
swresize
)
...
...
@@ -697,7 +696,7 @@ HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
ap
.
cbAlign
=
1
;
ap
.
cbPrefix
=
0
;
out
=
(
OutputPin
*
)
capBox
->
pOut
;
out
=
(
Base
OutputPin
*
)
capBox
->
pOut
;
hr
=
IMemInputPin_GetAllocator
(
out
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
...
...
dlls/qcap/vfwcapture.c
View file @
5c1409b5
...
...
@@ -35,7 +35,6 @@
#include "qcap_main.h"
#include "wine/debug.h"
#include "pin.h"
#include "capture.h"
#include "uuids.h"
#include "vfwmsgs.h"
...
...
@@ -78,7 +77,7 @@ typedef struct VfwCapture
/* VfwPin implementation */
typedef
struct
VfwPinImpl
{
OutputPin
pin
;
Base
OutputPin
pin
;
Capture
*
driver_info
;
VfwCapture
*
parent
;
const
IKsPropertySetVtbl
*
KSP_VT
;
...
...
@@ -786,13 +785,10 @@ VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
{
static
const
WCHAR
wszOutputPinName
[]
=
{
'O'
,
'u'
,
't'
,
'p'
,
'u'
,
't'
,
0
};
ALLOCATOR_PROPERTIES
ap
;
VfwPinImpl
*
pPinImpl
;
PIN_INFO
piOutput
;
HRESULT
hr
;
pPinImpl
=
CoTaskMemAlloc
(
sizeof
(
*
pPinImpl
)
);
if
(
!
pPinImpl
)
return
E_OUTOFMEMORY
;
ppPin
=
NULL
;
/* What we put here doesn't matter, the
driver function should override it then commit */
...
...
@@ -806,17 +802,15 @@ VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
lstrcpyW
(
piOutput
.
achName
,
wszOutputPinName
);
ObjectRefCount
(
TRUE
);
hr
=
OutputPin_Init
(
&
piOutput
,
&
ap
,
pCritSec
,
&
pPinImpl
->
pin
);
hr
=
BaseOutputPin_Construct
(
&
VfwPin_Vtbl
,
sizeof
(
VfwPinImpl
),
&
piOutput
,
&
ap
,
NULL
,
pCritSec
,
ppPin
);
if
(
SUCCEEDED
(
hr
))
{
VfwPinImpl
*
pPinImpl
=
(
VfwPinImpl
*
)
*
ppPin
;
pPinImpl
->
KSP_VT
=
&
KSP_VTable
;
pPinImpl
->
pin
.
pin
.
lpVtbl
=
&
VfwPin_Vtbl
;
*
ppPin
=
(
IPin
*
)(
&
pPinImpl
->
pin
.
pin
.
lpVtbl
);
return
S_OK
;
}
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
return
hr
;
}
static
HRESULT
WINAPI
VfwPin_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
...
...
@@ -924,9 +918,9 @@ static const IPinVtbl VfwPin_Vtbl =
VfwPin_QueryInterface
,
VfwPin_AddRef
,
VfwPin_Release
,
OutputPin
_Connect
,
OutputPin
_ReceiveConnection
,
OutputPin
_Disconnect
,
BaseOutputPinImpl
_Connect
,
BaseOutputPinImpl
_ReceiveConnection
,
BaseOutputPinImpl
_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
...
...
dlls/quartz/acmwrapper.c
View file @
5c1409b5
...
...
@@ -120,7 +120,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample
while
(
hr
==
S_OK
&&
ash
.
cbSrcLength
)
{
hr
=
OutputPin_GetDeliveryBuffer
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
&
pOutSample
,
NULL
,
NULL
,
0
);
hr
=
BaseOutputPinImpl_GetDeliveryBuffer
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
&
pOutSample
,
NULL
,
NULL
,
0
);
if
(
FAILED
(
hr
))
{
ERR
(
"Unable to get delivery buffer (%x)
\n
"
,
hr
);
...
...
@@ -205,7 +205,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample
TRACE
(
"Sample stop time: %u.%03u
\n
"
,
(
DWORD
)(
tStart
/
10000000
),
(
DWORD
)((
tStart
/
10000
)
%
1000
));
LeaveCriticalSection
(
&
This
->
tf
.
csFilter
);
hr
=
OutputPin_SendSample
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
pOutSample
);
hr
=
BaseOutputPinImpl_Deliver
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
pOutSample
);
EnterCriticalSection
(
&
This
->
tf
.
csFilter
);
if
(
hr
!=
S_OK
&&
hr
!=
VFW_E_NOT_CONNECTED
)
{
...
...
@@ -272,7 +272,7 @@ static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt)
This
->
has
=
drv
;
/* Update buffer size of media samples in output */
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
])
->
allocProps
.
cbBuffer
=
This
->
pWfOut
->
nAvgBytesPerSec
/
2
;
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
])
->
allocProps
.
cbBuffer
=
This
->
pWfOut
->
nAvgBytesPerSec
/
2
;
TRACE
(
"Connection accepted
\n
"
);
return
S_OK
;
}
...
...
dlls/quartz/avidec.c
View file @
5c1409b5
...
...
@@ -112,7 +112,7 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample)
/* Update input size to match sample size */
This
->
pBihIn
->
biSizeImage
=
cbSrcStream
;
hr
=
OutputPin_GetDeliveryBuffer
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
&
pOutSample
,
NULL
,
NULL
,
0
);
hr
=
BaseOutputPinImpl_GetDeliveryBuffer
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
&
pOutSample
,
NULL
,
NULL
,
0
);
if
(
FAILED
(
hr
))
{
ERR
(
"Unable to get delivery buffer (%x)
\n
"
,
hr
);
goto
error
;
...
...
@@ -149,7 +149,7 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample)
IMediaSample_SetTime
(
pOutSample
,
NULL
,
NULL
);
LeaveCriticalSection
(
&
This
->
tf
.
csFilter
);
hr
=
OutputPin_SendSample
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
pOutSample
);
hr
=
BaseOutputPinImpl_Deliver
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
],
pOutSample
);
if
(
hr
!=
S_OK
&&
hr
!=
VFW_E_NOT_CONNECTED
)
ERR
(
"Error sending sample (%x)
\n
"
,
hr
);
IMediaSample_Release
(
pOutSample
);
...
...
@@ -269,7 +269,7 @@ static HRESULT AVIDec_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt)
assert
(
0
);
/* Update buffer size of media samples in output */
((
OutputPin
*
)
This
->
tf
.
ppPins
[
1
])
->
allocProps
.
cbBuffer
=
This
->
pBihOut
->
biSizeImage
;
((
Base
OutputPin
*
)
This
->
tf
.
ppPins
[
1
])
->
allocProps
.
cbBuffer
=
This
->
pBihOut
->
biSizeImage
;
TRACE
(
"Connection accepted
\n
"
);
return
S_OK
;
...
...
dlls/quartz/avisplit.c
View file @
5c1409b5
...
...
@@ -311,7 +311,7 @@ static HRESULT AVISplitter_Receive(AVISplitterImpl *This, IMediaSample *sample,
IMediaSample_SetTime
(
sample
,
&
start
,
&
stop
);
hr
=
OutputPin_SendSample
(
&
pin
->
pin
,
sample
);
hr
=
BaseOutputPinImpl_Deliver
((
BaseOutputPin
*
)
&
pin
->
pin
,
sample
);
/* Uncomment this if you want to debug the time differences between the
* different streams, it is useful for that
...
...
dlls/quartz/enummedia.c
View file @
5c1409b5
...
...
@@ -24,16 +24,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
quartz
);
BOOL
CompareMediaTypes
(
const
AM_MEDIA_TYPE
*
pmt1
,
const
AM_MEDIA_TYPE
*
pmt2
,
BOOL
bWildcards
)
{
TRACE
(
"pmt1: "
);
dump_AM_MEDIA_TYPE
(
pmt1
);
TRACE
(
"pmt2: "
);
dump_AM_MEDIA_TYPE
(
pmt2
);
return
(((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
majortype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
majortype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
majortype
,
&
pmt2
->
majortype
))
&&
((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
subtype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
subtype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
subtype
,
&
pmt2
->
subtype
)));
}
void
dump_AM_MEDIA_TYPE
(
const
AM_MEDIA_TYPE
*
pmt
)
{
if
(
!
pmt
)
...
...
dlls/quartz/filesource.c
View file @
5c1409b5
...
...
@@ -773,7 +773,7 @@ typedef struct DATAREQUEST
typedef
struct
FileAsyncReader
{
OutputPin
pin
;
Base
OutputPin
pin
;
const
struct
IAsyncReaderVtbl
*
lpVtblAR
;
HANDLE
hFile
;
...
...
@@ -886,8 +886,8 @@ static const IPinVtbl FileAsyncReaderPin_Vtbl =
FileAsyncReaderPin_QueryInterface
,
BasePinImpl_AddRef
,
FileAsyncReaderPin_Release
,
OutputPin
_Connect
,
OutputPin
_ReceiveConnection
,
BaseOutputPinImpl
_Connect
,
BaseOutputPinImpl
_ReceiveConnection
,
BasePinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
...
...
@@ -897,19 +897,19 @@ static const IPinVtbl FileAsyncReaderPin_Vtbl =
FileAsyncReaderPin_QueryAccept
,
FileAsyncReaderPin_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
OutputPin
_EndOfStream
,
OutputPin
_BeginFlush
,
OutputPin
_EndFlush
,
OutputPin
_NewSegment
BaseOutputPinImpl
_EndOfStream
,
BaseOutputPinImpl
_BeginFlush
,
BaseOutputPinImpl
_EndFlush
,
BaseOutputPinImpl
_NewSegment
};
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* this differs from standard OutputPin_
ConnectSpecific
only in that it
/* this differs from standard OutputPin_
AttemptConnection
only in that it
* doesn't need the IMemInputPin interface on the receiving pin */
static
HRESULT
FileAsyncReaderPin_ConnectSpecific
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
static
HRESULT
WINAPI
FileAsyncReaderPin_AttemptConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
BaseOutputPin
*
This
=
(
Base
OutputPin
*
)
iface
;
HRESULT
hr
;
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
...
...
@@ -943,7 +943,7 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
piOutput
.
dir
=
PINDIR_OUTPUT
;
piOutput
.
pFilter
=
pBaseFilter
;
strcpyW
(
piOutput
.
achName
,
wszOutputPinName
);
hr
=
OutputPin_Construct
(
&
FileAsyncReaderPin_Vtbl
,
sizeof
(
FileAsyncReader
),
&
piOutput
,
NULL
,
pCritSec
,
ppPin
);
hr
=
BaseOutputPin_Construct
(
&
FileAsyncReaderPin_Vtbl
,
sizeof
(
FileAsyncReader
),
&
piOutput
,
NULL
,
FileAsyncReaderPin_AttemptConnection
,
pCritSec
,
ppPin
);
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -954,7 +954,6 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
pPinImpl
->
sample_list
=
NULL
;
pPinImpl
->
handle_list
=
NULL
;
pPinImpl
->
queued_number
=
0
;
pPinImpl
->
pin
.
pConnectSpecific
=
FileAsyncReaderPin_ConnectSpecific
;
InitializeCriticalSection
(
&
pPinImpl
->
csList
);
pPinImpl
->
csList
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": FileAsyncReader.csList"
);
}
...
...
dlls/quartz/mpegsplit.c
View file @
5c1409b5
...
...
@@ -226,7 +226,7 @@ static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
IMediaSample_SetTime
(
pCurrentSample
,
&
time
,
&
This
->
position
);
hr
=
OutputPin_SendSample
(
&
pOutputPin
->
pin
,
pCurrentSample
);
hr
=
BaseOutputPinImpl_Deliver
((
BaseOutputPin
*
)
&
pOutputPin
->
pin
,
pCurrentSample
);
if
(
hr
!=
S_OK
)
{
...
...
dlls/quartz/parser.c
View file @
5c1409b5
...
...
@@ -234,7 +234,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface)
for
(
i
=
1
;
i
<
(
This
->
cStreams
+
1
);
i
++
)
{
OutputPin_DecommitAllocator
((
OutputPin
*
)
This
->
ppPins
[
i
]);
BaseOutputPinImpl_Inactive
((
Base
OutputPin
*
)
This
->
ppPins
[
i
]);
}
LeaveCriticalSection
(
&
This
->
csFilter
);
...
...
@@ -308,7 +308,7 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
for
(
i
=
1
;
i
<
(
This
->
cStreams
+
1
);
i
++
)
{
hr
=
OutputPin_CommitAllocator
((
OutputPin
*
)
This
->
ppPins
[
i
]);
hr
=
BaseOutputPinImpl_Active
((
Base
OutputPin
*
)
This
->
ppPins
[
i
]);
if
(
SUCCEEDED
(
hr
))
hr_any
=
hr
;
}
...
...
@@ -491,7 +491,7 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
This
->
ppPins
=
CoTaskMemAlloc
((
This
->
cStreams
+
2
)
*
sizeof
(
IPin
*
));
memcpy
(
This
->
ppPins
,
ppOldPins
,
(
This
->
cStreams
+
1
)
*
sizeof
(
IPin
*
));
hr
=
OutputPin_Construct
(
&
Parser_OutputPin_Vtbl
,
sizeof
(
Parser_OutputPin
),
piOutput
,
props
,
&
This
->
csFilter
,
This
->
ppPins
+
(
This
->
cStreams
+
1
));
hr
=
BaseOutputPin_Construct
(
&
Parser_OutputPin_Vtbl
,
sizeof
(
Parser_OutputPin
),
piOutput
,
props
,
NULL
,
&
This
->
csFilter
,
This
->
ppPins
+
(
This
->
cStreams
+
1
));
if
(
SUCCEEDED
(
hr
))
{
...
...
@@ -532,7 +532,7 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This)
for
(
i
=
0
;
i
<
This
->
cStreams
;
i
++
)
{
hr
=
OutputPin_DeliverDisconnect
((
OutputPin
*
)
ppOldPins
[
i
+
1
]);
hr
=
BaseOutputPinImpl_BreakConnect
((
Base
OutputPin
*
)
ppOldPins
[
i
+
1
]);
TRACE
(
"Disconnect: %08x
\n
"
,
hr
);
IPin_Release
(
ppOldPins
[
i
+
1
]);
}
...
...
@@ -684,7 +684,7 @@ static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin,
This
->
pin
.
alloc
=
parser
->
pInputPin
->
pAlloc
;
LeaveCriticalSection
(
This
->
pin
.
pin
.
pCritSec
);
return
OutputPin
_Connect
(
iface
,
pReceivePin
,
pmt
);
return
BaseOutputPinImpl
_Connect
(
iface
,
pReceivePin
,
pmt
);
}
static
HRESULT
WINAPI
Parser_OutputPin_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
)
...
...
@@ -703,8 +703,8 @@ static const IPinVtbl Parser_OutputPin_Vtbl =
BasePinImpl_AddRef
,
Parser_OutputPin_Release
,
Parser_OutputPin_Connect
,
OutputPin
_ReceiveConnection
,
OutputPin
_Disconnect
,
BaseOutputPinImpl
_ReceiveConnection
,
BaseOutputPinImpl
_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
...
...
@@ -713,10 +713,10 @@ static const IPinVtbl Parser_OutputPin_Vtbl =
Parser_OutputPin_QueryAccept
,
Parser_OutputPin_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
OutputPin
_EndOfStream
,
OutputPin
_BeginFlush
,
OutputPin
_EndFlush
,
OutputPin
_NewSegment
BaseOutputPinImpl
_EndOfStream
,
BaseOutputPinImpl
_BeginFlush
,
BaseOutputPinImpl
_EndFlush
,
BaseOutputPinImpl
_NewSegment
};
static
HRESULT
WINAPI
Parser_PullPin_Disconnect
(
IPin
*
iface
)
...
...
dlls/quartz/parser.h
View file @
5c1409b5
...
...
@@ -49,7 +49,7 @@ struct ParserImpl
typedef
struct
Parser_OutputPin
{
OutputPin
pin
;
Base
OutputPin
pin
;
AM_MEDIA_TYPE
*
pmt
;
LONGLONG
dwSamplesProcessed
;
...
...
dlls/quartz/pin.c
View file @
5c1409b5
...
...
@@ -30,7 +30,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
quartz
);
static
const
IPinVtbl
InputPin_Vtbl
;
static
const
IPinVtbl
OutputPin_Vtbl
;
static
const
IMemInputPinVtbl
MemInputPin_Vtbl
;
static
const
IPinVtbl
PullPin_Vtbl
;
...
...
@@ -510,391 +509,6 @@ static const IMemInputPinVtbl MemInputPin_Vtbl =
MemInputPin_ReceiveCanBlock
};
/*** OutputPin implementation ***/
HRESULT
WINAPI
OutputPin_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%s, %p)
\n
"
,
This
,
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_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
OutputPin_Release
(
IPin
*
iface
)
{
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
pin
.
refCount
);
TRACE
(
"(%p)->() Release from %d
\n
"
,
iface
,
refCount
+
1
);
if
(
!
refCount
)
{
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
CoTaskMemFree
(
This
);
return
0
;
}
return
refCount
;
}
HRESULT
WINAPI
OutputPin_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
HRESULT
hr
;
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%p, %p)
\n
"
,
This
,
iface
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* If we try to connect to ourself, we will definitely deadlock.
* There are other cases where we could deadlock too, but this
* catches the obvious case */
assert
(
pReceivePin
!=
iface
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
/* if we have been a specific type to connect with, then we can either connect
* with that or fail. We cannot choose different AM_MEDIA_TYPE */
if
(
pmt
&&
!
IsEqualGUID
(
&
pmt
->
majortype
,
&
GUID_NULL
)
&&
!
IsEqualGUID
(
&
pmt
->
subtype
,
&
GUID_NULL
))
hr
=
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmt
);
else
{
/* negotiate media type */
IEnumMediaTypes
*
pEnumCandidates
;
AM_MEDIA_TYPE
*
pmtCandidate
=
NULL
;
/* Candidate media type */
if
(
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
iface
,
&
pEnumCandidates
)))
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
/* try this filter's media types first */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
assert
(
pmtCandidate
);
dump_AM_MEDIA_TYPE
(
pmtCandidate
);
if
(
!
IsEqualGUID
(
&
FORMAT_None
,
&
pmtCandidate
->
formattype
)
&&
!
IsEqualGUID
(
&
GUID_NULL
,
&
pmtCandidate
->
formattype
))
assert
(
pmtCandidate
->
pbFormat
);
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
pmtCandidate
=
NULL
;
}
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* then try receiver filter's media types */
if
(
hr
!=
S_OK
&&
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
pReceivePin
,
&
pEnumCandidates
)))
/* if we haven't already connected successfully */
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
assert
(
pmtCandidate
);
dump_AM_MEDIA_TYPE
(
pmtCandidate
);
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pConnectSpecific
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
pmtCandidate
=
NULL
;
}
/* while */
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* if not found */
}
/* if negotiate media type */
}
/* if succeeded */
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
HRESULT
WINAPI
OutputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ERR
(
"Incoming connection on an output pin! (%p, %p)
\n
"
,
pReceivePin
,
pmt
);
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
OutputPin_Disconnect
(
IPin
*
iface
)
{
HRESULT
hr
;
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
TRACE
(
"()
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
This
->
pMemInputPin
)
{
IMemInputPin_Release
(
This
->
pMemInputPin
);
This
->
pMemInputPin
=
NULL
;
}
if
(
This
->
pin
.
pConnectedTo
)
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
ZeroMemory
(
&
This
->
pin
.
mtCurrent
,
sizeof
(
This
->
pin
.
mtCurrent
));
hr
=
S_OK
;
}
else
hr
=
S_FALSE
;
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
HRESULT
WINAPI
OutputPin_EndOfStream
(
IPin
*
iface
)
{
TRACE
(
"()
\n
"
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
OutputPin_BeginFlush
(
IPin
*
iface
)
{
TRACE
(
"(%p)->()
\n
"
,
iface
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
OutputPin_EndFlush
(
IPin
*
iface
)
{
TRACE
(
"(%p)->()
\n
"
,
iface
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
OutputPin_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
)
{
TRACE
(
"(%p)->(%x%08x, %x%08x, %e)
\n
"
,
iface
,
(
ULONG
)(
tStart
>>
32
),
(
ULONG
)
tStart
,
(
ULONG
)(
tStop
>>
32
),
(
ULONG
)
tStop
,
dRate
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
static
const
IPinVtbl
OutputPin_Vtbl
=
{
OutputPin_QueryInterface
,
BasePinImpl_AddRef
,
OutputPin_Release
,
OutputPin_Connect
,
OutputPin_ReceiveConnection
,
OutputPin_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
BasePinImpl_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
OutputPin_EndOfStream
,
OutputPin_BeginFlush
,
OutputPin_EndFlush
,
OutputPin_NewSegment
};
HRESULT
OutputPin_GetDeliveryBuffer
(
OutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
)
{
HRESULT
hr
;
TRACE
(
"(%p, %p, %p, %x)
\n
"
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_GetBuffer
(
pAlloc
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMediaSample_SetTime
(
*
ppSample
,
tStart
,
tStop
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
HRESULT
OutputPin_SendSample
(
OutputPin
*
This
,
IMediaSample
*
pSample
)
{
HRESULT
hr
=
S_OK
;
IMemInputPin
*
pMemConnected
=
NULL
;
PIN_INFO
pinInfo
;
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
/* we don't have the lock held when using This->pMemInputPin,
* so we need to AddRef it to stop it being deleted while we are
* using it. Same with its filter. */
pMemConnected
=
This
->
pMemInputPin
;
IMemInputPin_AddRef
(
pMemConnected
);
hr
=
IPin_QueryPinInfo
(
This
->
pin
.
pConnectedTo
,
&
pinInfo
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
SUCCEEDED
(
hr
))
{
/* NOTE: if we are in a critical section when Receive is called
* then it causes some problems (most notably with the native Video
* Renderer) if we are re-entered for whatever reason */
hr
=
IMemInputPin_Receive
(
pMemConnected
,
pSample
);
/* If the filter's destroyed, tell upstream to stop sending data */
if
(
IBaseFilter_Release
(
pinInfo
.
pFilter
)
==
0
&&
SUCCEEDED
(
hr
))
hr
=
S_FALSE
;
}
if
(
pMemConnected
)
IMemInputPin_Release
(
pMemConnected
);
return
hr
;
}
HRESULT
OutputPin_CommitAllocator
(
OutputPin
*
This
)
{
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Commit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
"--> %08x
\n
"
,
hr
);
return
hr
;
}
HRESULT
OutputPin_DecommitAllocator
(
OutputPin
*
This
)
{
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Decommit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
"--> %08x
\n
"
,
hr
);
return
hr
;
}
HRESULT
OutputPin_DeliverDisconnect
(
OutputPin
*
This
)
{
HRESULT
hr
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
if
(
!
This
->
custom_allocator
)
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Decommit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IPin_Disconnect
(
This
->
pin
.
pConnectedTo
);
}
else
/* Kill the allocator! */
{
hr
=
IPin_Disconnect
(
This
->
pin
.
pConnectedTo
);
}
IPin_Disconnect
((
IPin
*
)
This
);
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
/*** PullPin implementation ***/
static
HRESULT
PullPin_Init
(
const
IPinVtbl
*
PullPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
SAMPLEPROC_PULL
pSampleProc
,
LPVOID
pUserData
,
...
...
@@ -1524,83 +1138,6 @@ static const IPinVtbl PullPin_Vtbl =
/*** The Construct functions ***/
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* NOTE: not part of standard interface */
static
HRESULT
OutputPin_ConnectSpecific
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
OutputPin
*
This
=
(
OutputPin
*
)
iface
;
HRESULT
hr
;
IMemAllocator
*
pMemAlloc
=
NULL
;
ALLOCATOR_PROPERTIES
actual
;
/* FIXME: should we put the actual props back in to This? */
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* FIXME: call queryacceptproc */
This
->
pin
.
pConnectedTo
=
pReceivePin
;
IPin_AddRef
(
pReceivePin
);
CopyMediaType
(
&
This
->
pin
.
mtCurrent
,
pmt
);
hr
=
IPin_ReceiveConnection
(
pReceivePin
,
iface
,
pmt
);
/* get the IMemInputPin interface we will use to deliver samples to the
* connected pin */
if
(
SUCCEEDED
(
hr
))
{
This
->
pMemInputPin
=
NULL
;
hr
=
IPin_QueryInterface
(
pReceivePin
,
&
IID_IMemInputPin
,
(
LPVOID
)
&
This
->
pMemInputPin
);
if
(
SUCCEEDED
(
hr
)
&&
!
This
->
custom_allocator
)
{
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pMemAlloc
);
if
(
hr
==
VFW_E_NO_ALLOCATOR
)
/* Input pin provides no allocator, use standard memory allocator */
hr
=
CoCreateInstance
(
&
CLSID_MemoryAllocator
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_IMemAllocator
,
(
LPVOID
*
)
&
pMemAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_SetProperties
(
pMemAlloc
,
&
This
->
allocProps
,
&
actual
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemInputPin_NotifyAllocator
(
This
->
pMemInputPin
,
pMemAlloc
,
This
->
readonly
);
if
(
pMemAlloc
)
IMemAllocator_Release
(
pMemAlloc
);
}
else
if
(
SUCCEEDED
(
hr
))
{
if
(
This
->
alloc
)
{
hr
=
IMemInputPin_NotifyAllocator
(
This
->
pMemInputPin
,
This
->
alloc
,
This
->
readonly
);
}
else
hr
=
VFW_E_NO_ALLOCATOR
;
}
/* break connection if we couldn't get the allocator */
if
(
FAILED
(
hr
))
{
if
(
This
->
pMemInputPin
)
IMemInputPin_Release
(
This
->
pMemInputPin
);
This
->
pMemInputPin
=
NULL
;
IPin_Disconnect
(
pReceivePin
);
}
}
if
(
FAILED
(
hr
))
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
}
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
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
)
{
...
...
@@ -1631,40 +1168,6 @@ static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPi
return
S_OK
;
}
static
HRESULT
OutputPin_Init
(
const
IPinVtbl
*
OutputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
const
ALLOCATOR_PROPERTIES
*
props
,
LPCRITICAL_SECTION
pCritSec
,
OutputPin
*
pPinImpl
)
{
TRACE
(
"
\n
"
);
/* Common attributes */
pPinImpl
->
pin
.
lpVtbl
=
OutputPin_Vtbl
;
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
));
/* Output pin attributes */
pPinImpl
->
pMemInputPin
=
NULL
;
pPinImpl
->
pConnectSpecific
=
OutputPin_ConnectSpecific
;
/* If custom_allocator is set, you will need to specify an allocator
* in the alloc member of the struct before an output pin can connect
*/
pPinImpl
->
custom_allocator
=
0
;
pPinImpl
->
alloc
=
NULL
;
pPinImpl
->
readonly
=
FALSE
;
if
(
props
)
{
pPinImpl
->
allocProps
=
*
props
;
if
(
pPinImpl
->
allocProps
.
cbAlign
==
0
)
pPinImpl
->
allocProps
.
cbAlign
=
1
;
}
else
ZeroMemory
(
&
pPinImpl
->
allocProps
,
sizeof
(
pPinImpl
->
allocProps
));
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
;
...
...
@@ -1691,32 +1194,3 @@ HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinI
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
HRESULT
OutputPin_Construct
(
const
IPinVtbl
*
OutputPin_Vtbl
,
LONG
outputpin_size
,
const
PIN_INFO
*
pPinInfo
,
ALLOCATOR_PROPERTIES
*
props
,
LPCRITICAL_SECTION
pCritSec
,
IPin
**
ppPin
)
{
OutputPin
*
pPinImpl
;
*
ppPin
=
NULL
;
if
(
pPinInfo
->
dir
!=
PINDIR_OUTPUT
)
{
ERR
(
"Pin direction(%x) != PINDIR_OUTPUT
\n
"
,
pPinInfo
->
dir
);
return
E_INVALIDARG
;
}
assert
(
outputpin_size
>=
sizeof
(
OutputPin
));
pPinImpl
=
CoTaskMemAlloc
(
outputpin_size
);
if
(
!
pPinImpl
)
return
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
OutputPin_Init
(
OutputPin_Vtbl
,
pPinInfo
,
props
,
pCritSec
,
pPinImpl
)))
{
*
ppPin
=
(
IPin
*
)(
&
pPinImpl
->
pin
.
lpVtbl
);
return
S_OK
;
}
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
dlls/quartz/pin.h
View file @
5c1409b5
...
...
@@ -84,19 +84,6 @@ typedef struct InputPin
IMemAllocator
*
preferred_allocator
;
}
InputPin
;
typedef
struct
OutputPin
{
/* inheritance C style! */
BasePin
pin
;
IMemInputPin
*
pMemInputPin
;
HRESULT
(
*
pConnectSpecific
)(
IPin
*
iface
,
IPin
*
pReceiver
,
const
AM_MEDIA_TYPE
*
pmt
);
BOOL
custom_allocator
;
IMemAllocator
*
alloc
;
BOOL
readonly
;
ALLOCATOR_PROPERTIES
allocProps
;
}
OutputPin
;
typedef
struct
PullPin
{
/* inheritance C style! */
...
...
@@ -134,7 +121,6 @@ typedef struct PullPin
/*** 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
OutputPin_Construct
(
const
IPinVtbl
*
OutputPin_Vtbl
,
LONG
outputpin_size
,
const
PIN_INFO
*
pPinInfo
,
ALLOCATOR_PROPERTIES
*
props
,
LPCRITICAL_SECTION
pCritSec
,
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
);
/**************************/
...
...
@@ -151,23 +137,6 @@ 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
);
/* Output Pin */
HRESULT
WINAPI
OutputPin_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
);
ULONG
WINAPI
OutputPin_Release
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
OutputPin_Disconnect
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
OutputPin_EndOfStream
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_BeginFlush
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_EndFlush
(
IPin
*
iface
);
HRESULT
WINAPI
OutputPin_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
HRESULT
OutputPin_CommitAllocator
(
OutputPin
*
This
);
HRESULT
OutputPin_DecommitAllocator
(
OutputPin
*
This
);
HRESULT
OutputPin_GetDeliveryBuffer
(
OutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
);
HRESULT
OutputPin_SendSample
(
OutputPin
*
This
,
IMediaSample
*
pSample
);
HRESULT
OutputPin_DeliverDisconnect
(
OutputPin
*
This
);
/* 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 @
5c1409b5
...
...
@@ -117,7 +117,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
((
InputPin
*
)
pTransformFilter
->
ppPins
[
0
])
->
pUserData
=
pTransformFilter
->
ppPins
[
0
];
hr
=
OutputPin_Construct
(
&
TransformFilter_OutputPin_Vtbl
,
sizeof
(
OutputPin
),
&
piOutput
,
&
props
,
&
pTransformFilter
->
csFilter
,
&
pTransformFilter
->
ppPins
[
1
]);
hr
=
BaseOutputPin_Construct
(
&
TransformFilter_OutputPin_Vtbl
,
sizeof
(
BaseOutputPin
),
&
piOutput
,
&
props
,
NULL
,
&
pTransformFilter
->
csFilter
,
&
pTransformFilter
->
ppPins
[
1
]);
if
(
FAILED
(
hr
))
ERR
(
"Cannot create output pin (%x)
\n
"
,
hr
);
...
...
@@ -295,7 +295,7 @@ static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tS
if
(
This
->
pFuncsTable
->
pfnProcessBegin
)
hr
=
This
->
pFuncsTable
->
pfnProcessBegin
(
This
);
if
(
SUCCEEDED
(
hr
))
hr
=
OutputPin_CommitAllocator
((
OutputPin
*
)
This
->
ppPins
[
1
]);
hr
=
BaseOutputPinImpl_Active
((
Base
OutputPin
*
)
This
->
ppPins
[
1
]);
}
if
(
SUCCEEDED
(
hr
))
...
...
@@ -624,12 +624,12 @@ static HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumM
static
const
IPinVtbl
TransformFilter_OutputPin_Vtbl
=
{
OutputPin
_QueryInterface
,
BaseOutputPinImpl
_QueryInterface
,
BasePinImpl_AddRef
,
OutputPin
_Release
,
OutputPin
_Connect
,
OutputPin
_ReceiveConnection
,
OutputPin
_Disconnect
,
BaseOutputPinImpl
_Release
,
BaseOutputPinImpl
_Connect
,
BaseOutputPinImpl
_ReceiveConnection
,
BaseOutputPinImpl
_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
...
...
@@ -638,8 +638,8 @@ static const IPinVtbl TransformFilter_OutputPin_Vtbl =
TransformFilter_Output_QueryAccept
,
TransformFilter_Output_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
OutputPin
_EndOfStream
,
OutputPin
_BeginFlush
,
OutputPin
_EndFlush
,
OutputPin
_NewSegment
BaseOutputPinImpl
_EndOfStream
,
BaseOutputPinImpl
_BeginFlush
,
BaseOutputPinImpl
_EndFlush
,
BaseOutputPinImpl
_NewSegment
};
dlls/quartz/waveparser.c
View file @
5c1409b5
...
...
@@ -132,7 +132,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR
IMediaSample_SetTime
(
pSample
,
&
tAviStart
,
&
tAviStop
);
hr
=
OutputPin_SendSample
(
&
pOutputPin
->
pin
,
pSample
);
hr
=
BaseOutputPinImpl_Deliver
(
&
pOutputPin
->
pin
,
pSample
);
if
(
hr
!=
S_OK
&&
hr
!=
S_FALSE
&&
hr
!=
VFW_E_WRONG_STATE
)
ERR
(
"Error sending sample (%x)
\n
"
,
hr
);
else
if
(
hr
!=
S_OK
)
...
...
dlls/strmbase/pin.c
View file @
5c1409b5
...
...
@@ -31,6 +31,8 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
strmbase
);
static
const
IPinVtbl
OutputPin_Vtbl
;
static
void
Copy_PinInfo
(
PIN_INFO
*
pDest
,
const
PIN_INFO
*
pSrc
)
{
/* Tempting to just do a memcpy, but the name field is
...
...
@@ -42,6 +44,23 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
pDest
->
pFilter
=
pSrc
->
pFilter
;
}
static
void
dump_AM_MEDIA_TYPE
(
const
AM_MEDIA_TYPE
*
pmt
)
{
if
(
!
pmt
)
return
;
TRACE
(
"
\t
%s
\n\t
%s
\n\t
...
\n\t
%s
\n
"
,
debugstr_guid
(
&
pmt
->
majortype
),
debugstr_guid
(
&
pmt
->
subtype
),
debugstr_guid
(
&
pmt
->
formattype
));
}
static
BOOL
CompareMediaTypes
(
const
AM_MEDIA_TYPE
*
pmt1
,
const
AM_MEDIA_TYPE
*
pmt2
,
BOOL
bWildcards
)
{
TRACE
(
"pmt1: "
);
dump_AM_MEDIA_TYPE
(
pmt1
);
TRACE
(
"pmt2: "
);
dump_AM_MEDIA_TYPE
(
pmt2
);
return
(((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
majortype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
majortype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
majortype
,
&
pmt2
->
majortype
))
&&
((
bWildcards
&&
(
IsEqualGUID
(
&
pmt1
->
subtype
,
&
GUID_NULL
)
||
IsEqualGUID
(
&
pmt2
->
subtype
,
&
GUID_NULL
)))
||
IsEqualGUID
(
&
pmt1
->
subtype
,
&
pmt2
->
subtype
)));
}
/*** Common Base Pin function */
HRESULT
WINAPI
BasePinImpl_GetMediaType
(
IPin
*
iface
,
int
iPosition
,
AM_MEDIA_TYPE
*
pmt
)
{
...
...
@@ -205,3 +224,537 @@ HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin,
return
E_NOTIMPL
;
/* to tell caller that all input pins connected to all output pins */
}
/*** OutputPin implementation ***/
HRESULT
WINAPI
BaseOutputPinImpl_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
)
{
BaseOutputPin
*
This
=
(
BaseOutputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%s, %p)
\n
"
,
This
,
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_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
BaseOutputPinImpl_Release
(
IPin
*
iface
)
{
BaseOutputPin
*
This
=
(
BaseOutputPin
*
)
iface
;
ULONG
refCount
=
InterlockedDecrement
(
&
This
->
pin
.
refCount
);
TRACE
(
"(%p)->() Release from %d
\n
"
,
iface
,
refCount
+
1
);
if
(
!
refCount
)
{
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
CoTaskMemFree
(
This
);
return
0
;
}
return
refCount
;
}
HRESULT
WINAPI
BaseOutputPinImpl_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
HRESULT
hr
;
BaseOutputPin
*
This
=
(
BaseOutputPin
*
)
iface
;
TRACE
(
"(%p/%p)->(%p, %p)
\n
"
,
This
,
iface
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* If we try to connect to ourself, we will definitely deadlock.
* There are other cases where we could deadlock too, but this
* catches the obvious case */
assert
(
pReceivePin
!=
iface
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
/* if we have been a specific type to connect with, then we can either connect
* with that or fail. We cannot choose different AM_MEDIA_TYPE */
if
(
pmt
&&
!
IsEqualGUID
(
&
pmt
->
majortype
,
&
GUID_NULL
)
&&
!
IsEqualGUID
(
&
pmt
->
subtype
,
&
GUID_NULL
))
hr
=
This
->
pAttemptConnection
(
iface
,
pReceivePin
,
pmt
);
else
{
/* negotiate media type */
IEnumMediaTypes
*
pEnumCandidates
;
AM_MEDIA_TYPE
*
pmtCandidate
=
NULL
;
/* Candidate media type */
if
(
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
iface
,
&
pEnumCandidates
)))
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
/* try this filter's media types first */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
assert
(
pmtCandidate
);
dump_AM_MEDIA_TYPE
(
pmtCandidate
);
if
(
!
IsEqualGUID
(
&
FORMAT_None
,
&
pmtCandidate
->
formattype
)
&&
!
IsEqualGUID
(
&
GUID_NULL
,
&
pmtCandidate
->
formattype
))
assert
(
pmtCandidate
->
pbFormat
);
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pAttemptConnection
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
pmtCandidate
=
NULL
;
}
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* then try receiver filter's media types */
if
(
hr
!=
S_OK
&&
SUCCEEDED
(
hr
=
IPin_EnumMediaTypes
(
pReceivePin
,
&
pEnumCandidates
)))
/* if we haven't already connected successfully */
{
hr
=
VFW_E_NO_ACCEPTABLE_TYPES
;
/* Assume the worst, but set to S_OK if connected successfully */
while
(
S_OK
==
IEnumMediaTypes_Next
(
pEnumCandidates
,
1
,
&
pmtCandidate
,
NULL
))
{
assert
(
pmtCandidate
);
dump_AM_MEDIA_TYPE
(
pmtCandidate
);
if
((
!
pmt
||
CompareMediaTypes
(
pmt
,
pmtCandidate
,
TRUE
)
)
&&
(
This
->
pAttemptConnection
(
iface
,
pReceivePin
,
pmtCandidate
)
==
S_OK
))
{
hr
=
S_OK
;
DeleteMediaType
(
pmtCandidate
);
break
;
}
DeleteMediaType
(
pmtCandidate
);
pmtCandidate
=
NULL
;
}
/* while */
IEnumMediaTypes_Release
(
pEnumCandidates
);
}
/* if not found */
}
/* if negotiate media type */
}
/* if succeeded */
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
HRESULT
WINAPI
BaseOutputPinImpl_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
ERR
(
"Incoming connection on an output pin! (%p, %p)
\n
"
,
pReceivePin
,
pmt
);
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
BaseOutputPinImpl_Disconnect
(
IPin
*
iface
)
{
HRESULT
hr
;
BaseOutputPin
*
This
=
(
BaseOutputPin
*
)
iface
;
TRACE
(
"()
\n
"
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
This
->
pMemInputPin
)
{
IMemInputPin_Release
(
This
->
pMemInputPin
);
This
->
pMemInputPin
=
NULL
;
}
if
(
This
->
pin
.
pConnectedTo
)
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
ZeroMemory
(
&
This
->
pin
.
mtCurrent
,
sizeof
(
This
->
pin
.
mtCurrent
));
hr
=
S_OK
;
}
else
hr
=
S_FALSE
;
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
HRESULT
WINAPI
BaseOutputPinImpl_EndOfStream
(
IPin
*
iface
)
{
TRACE
(
"()
\n
"
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
BaseOutputPinImpl_BeginFlush
(
IPin
*
iface
)
{
TRACE
(
"(%p)->()
\n
"
,
iface
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
BaseOutputPinImpl_EndFlush
(
IPin
*
iface
)
{
TRACE
(
"(%p)->()
\n
"
,
iface
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
HRESULT
WINAPI
BaseOutputPinImpl_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
)
{
TRACE
(
"(%p)->(%x%08x, %x%08x, %e)
\n
"
,
iface
,
(
ULONG
)(
tStart
>>
32
),
(
ULONG
)
tStart
,
(
ULONG
)(
tStop
>>
32
),
(
ULONG
)
tStop
,
dRate
);
/* not supposed to do anything in an output pin */
return
E_UNEXPECTED
;
}
static
const
IPinVtbl
OutputPin_Vtbl
=
{
BaseOutputPinImpl_QueryInterface
,
BasePinImpl_AddRef
,
BaseOutputPinImpl_Release
,
BaseOutputPinImpl_Connect
,
BaseOutputPinImpl_ReceiveConnection
,
BaseOutputPinImpl_Disconnect
,
BasePinImpl_ConnectedTo
,
BasePinImpl_ConnectionMediaType
,
BasePinImpl_QueryPinInfo
,
BasePinImpl_QueryDirection
,
BasePinImpl_QueryId
,
BasePinImpl_QueryAccept
,
BasePinImpl_EnumMediaTypes
,
BasePinImpl_QueryInternalConnections
,
BaseOutputPinImpl_EndOfStream
,
BaseOutputPinImpl_BeginFlush
,
BaseOutputPinImpl_EndFlush
,
BaseOutputPinImpl_NewSegment
};
HRESULT
WINAPI
BaseOutputPinImpl_GetDeliveryBuffer
(
BaseOutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
)
{
HRESULT
hr
;
TRACE
(
"(%p, %p, %p, %x)
\n
"
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_GetBuffer
(
pAlloc
,
ppSample
,
tStart
,
tStop
,
dwFlags
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMediaSample_SetTime
(
*
ppSample
,
tStart
,
tStop
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
/* replaces OutputPin_SendSample */
HRESULT
WINAPI
BaseOutputPinImpl_Deliver
(
BaseOutputPin
*
This
,
IMediaSample
*
pSample
)
{
HRESULT
hr
=
S_OK
;
IMemInputPin
*
pMemConnected
=
NULL
;
PIN_INFO
pinInfo
;
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
/* we don't have the lock held when using This->pMemInputPin,
* so we need to AddRef it to stop it being deleted while we are
* using it. Same with its filter. */
pMemConnected
=
This
->
pMemInputPin
;
IMemInputPin_AddRef
(
pMemConnected
);
hr
=
IPin_QueryPinInfo
(
This
->
pin
.
pConnectedTo
,
&
pinInfo
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
if
(
SUCCEEDED
(
hr
))
{
/* NOTE: if we are in a critical section when Receive is called
* then it causes some problems (most notably with the native Video
* Renderer) if we are re-entered for whatever reason */
hr
=
IMemInputPin_Receive
(
pMemConnected
,
pSample
);
/* If the filter's destroyed, tell upstream to stop sending data */
if
(
IBaseFilter_Release
(
pinInfo
.
pFilter
)
==
0
&&
SUCCEEDED
(
hr
))
hr
=
S_FALSE
;
}
if
(
pMemConnected
)
IMemInputPin_Release
(
pMemConnected
);
return
hr
;
}
/* replaces OutputPin_CommitAllocator */
HRESULT
WINAPI
BaseOutputPinImpl_Active
(
BaseOutputPin
*
This
)
{
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Commit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
"--> %08x
\n
"
,
hr
);
return
hr
;
}
/* replaces OutputPin_DecommitAllocator */
HRESULT
WINAPI
BaseOutputPinImpl_Inactive
(
BaseOutputPin
*
This
)
{
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Decommit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
}
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
TRACE
(
"--> %08x
\n
"
,
hr
);
return
hr
;
}
/* replaces OutputPin_DeliverDisconnect */
HRESULT
WINAPI
BaseOutputPinImpl_BreakConnect
(
BaseOutputPin
*
This
)
{
HRESULT
hr
;
TRACE
(
"(%p)->()
\n
"
,
This
);
EnterCriticalSection
(
This
->
pin
.
pCritSec
);
{
if
(
!
This
->
pin
.
pConnectedTo
||
!
This
->
pMemInputPin
)
hr
=
VFW_E_NOT_CONNECTED
;
else
if
(
!
This
->
custom_allocator
)
{
IMemAllocator
*
pAlloc
=
NULL
;
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_Decommit
(
pAlloc
);
if
(
pAlloc
)
IMemAllocator_Release
(
pAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IPin_Disconnect
(
This
->
pin
.
pConnectedTo
);
}
else
/* Kill the allocator! */
{
hr
=
IPin_Disconnect
(
This
->
pin
.
pConnectedTo
);
}
IPin_Disconnect
((
IPin
*
)
This
);
}
LeaveCriticalSection
(
This
->
pin
.
pCritSec
);
return
hr
;
}
/*** The Construct functions ***/
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
static
HRESULT
WINAPI
OutputPin_AttemptConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
)
{
BaseOutputPin
*
This
=
(
BaseOutputPin
*
)
iface
;
HRESULT
hr
;
IMemAllocator
*
pMemAlloc
=
NULL
;
ALLOCATOR_PROPERTIES
actual
;
/* FIXME: should we put the actual props back in to This? */
TRACE
(
"(%p, %p)
\n
"
,
pReceivePin
,
pmt
);
dump_AM_MEDIA_TYPE
(
pmt
);
/* FIXME: call queryacceptproc */
This
->
pin
.
pConnectedTo
=
pReceivePin
;
IPin_AddRef
(
pReceivePin
);
CopyMediaType
(
&
This
->
pin
.
mtCurrent
,
pmt
);
hr
=
IPin_ReceiveConnection
(
pReceivePin
,
iface
,
pmt
);
/* get the IMemInputPin interface we will use to deliver samples to the
* connected pin */
if
(
SUCCEEDED
(
hr
))
{
This
->
pMemInputPin
=
NULL
;
hr
=
IPin_QueryInterface
(
pReceivePin
,
&
IID_IMemInputPin
,
(
LPVOID
)
&
This
->
pMemInputPin
);
if
(
SUCCEEDED
(
hr
)
&&
!
This
->
custom_allocator
)
{
hr
=
IMemInputPin_GetAllocator
(
This
->
pMemInputPin
,
&
pMemAlloc
);
if
(
hr
==
VFW_E_NO_ALLOCATOR
)
/* Input pin provides no allocator, use standard memory allocator */
hr
=
CoCreateInstance
(
&
CLSID_MemoryAllocator
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_IMemAllocator
,
(
LPVOID
*
)
&
pMemAlloc
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemAllocator_SetProperties
(
pMemAlloc
,
&
This
->
allocProps
,
&
actual
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMemInputPin_NotifyAllocator
(
This
->
pMemInputPin
,
pMemAlloc
,
This
->
readonly
);
if
(
pMemAlloc
)
IMemAllocator_Release
(
pMemAlloc
);
}
else
if
(
SUCCEEDED
(
hr
))
{
if
(
This
->
alloc
)
{
hr
=
IMemInputPin_NotifyAllocator
(
This
->
pMemInputPin
,
This
->
alloc
,
This
->
readonly
);
}
else
hr
=
VFW_E_NO_ALLOCATOR
;
}
/* break connection if we couldn't get the allocator */
if
(
FAILED
(
hr
))
{
if
(
This
->
pMemInputPin
)
IMemInputPin_Release
(
This
->
pMemInputPin
);
This
->
pMemInputPin
=
NULL
;
IPin_Disconnect
(
pReceivePin
);
}
}
if
(
FAILED
(
hr
))
{
IPin_Release
(
This
->
pin
.
pConnectedTo
);
This
->
pin
.
pConnectedTo
=
NULL
;
FreeMediaType
(
&
This
->
pin
.
mtCurrent
);
}
TRACE
(
" -- %x
\n
"
,
hr
);
return
hr
;
}
static
HRESULT
OutputPin_Init
(
const
IPinVtbl
*
OutputPin_Vtbl
,
const
PIN_INFO
*
pPinInfo
,
const
ALLOCATOR_PROPERTIES
*
props
,
BasePin_AttemptConnection
pConnectProc
,
LPCRITICAL_SECTION
pCritSec
,
BaseOutputPin
*
pPinImpl
)
{
TRACE
(
"
\n
"
);
/* Common attributes */
pPinImpl
->
pin
.
lpVtbl
=
OutputPin_Vtbl
;
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
));
/* Output pin attributes */
pPinImpl
->
pMemInputPin
=
NULL
;
if
(
pConnectProc
)
pPinImpl
->
pAttemptConnection
=
pConnectProc
;
else
pPinImpl
->
pAttemptConnection
=
OutputPin_AttemptConnection
;
/* If custom_allocator is set, you will need to specify an allocator
* in the alloc member of the struct before an output pin can connect
*/
pPinImpl
->
custom_allocator
=
0
;
pPinImpl
->
alloc
=
NULL
;
pPinImpl
->
readonly
=
FALSE
;
if
(
props
)
{
pPinImpl
->
allocProps
=
*
props
;
if
(
pPinImpl
->
allocProps
.
cbAlign
==
0
)
pPinImpl
->
allocProps
.
cbAlign
=
1
;
}
else
ZeroMemory
(
&
pPinImpl
->
allocProps
,
sizeof
(
pPinImpl
->
allocProps
));
return
S_OK
;
}
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
)
{
BaseOutputPin
*
pPinImpl
;
*
ppPin
=
NULL
;
if
(
pPinInfo
->
dir
!=
PINDIR_OUTPUT
)
{
ERR
(
"Pin direction(%x) != PINDIR_OUTPUT
\n
"
,
pPinInfo
->
dir
);
return
E_INVALIDARG
;
}
assert
(
outputpin_size
>=
sizeof
(
BaseOutputPin
));
pPinImpl
=
CoTaskMemAlloc
(
outputpin_size
);
if
(
!
pPinImpl
)
return
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
OutputPin_Init
(
OutputPin_Vtbl
,
pPinInfo
,
props
,
pConnectProc
,
pCritSec
,
pPinImpl
)))
{
*
ppPin
=
(
IPin
*
)(
&
pPinImpl
->
pin
.
lpVtbl
);
return
S_OK
;
}
CoTaskMemFree
(
pPinImpl
);
return
E_FAIL
;
}
include/wine/strmbase.h
View file @
5c1409b5
...
...
@@ -26,6 +26,7 @@ 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
IPin
*
(
WINAPI
*
BaseFilter_GetPin
)(
IBaseFilter
*
iface
,
int
iPosition
);
typedef
LONG
(
WINAPI
*
BaseFilter_GetPinCount
)(
IBaseFilter
*
iface
);
...
...
@@ -47,6 +48,19 @@ typedef struct BasePin
AM_MEDIA_TYPE
mtCurrent
;
}
BasePin
;
typedef
struct
BaseOutputPin
{
/* inheritance C style! */
BasePin
pin
;
IMemInputPin
*
pMemInputPin
;
BasePin_AttemptConnection
pAttemptConnection
;
BOOL
custom_allocator
;
IMemAllocator
*
alloc
;
BOOL
readonly
;
ALLOCATOR_PROPERTIES
allocProps
;
}
BaseOutputPin
;
/* Base Pin */
HRESULT
WINAPI
BasePinImpl_GetMediaType
(
IPin
*
iface
,
int
iPosition
,
AM_MEDIA_TYPE
*
pmt
);
LONG
WINAPI
BasePinImpl_GetMediaTypeVersion
(
IPin
*
iface
);
...
...
@@ -60,3 +74,21 @@ HRESULT WINAPI BasePinImpl_QueryId(IPin * iface, LPWSTR * Id);
HRESULT
WINAPI
BasePinImpl_QueryAccept
(
IPin
*
iface
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BasePinImpl_EnumMediaTypes
(
IPin
*
iface
,
IEnumMediaTypes
**
ppEnum
);
HRESULT
WINAPI
BasePinImpl_QueryInternalConnections
(
IPin
*
iface
,
IPin
**
apPin
,
ULONG
*
cPin
);
/* Base Output Pin */
HRESULT
WINAPI
BaseOutputPinImpl_QueryInterface
(
IPin
*
iface
,
REFIID
riid
,
LPVOID
*
ppv
);
ULONG
WINAPI
BaseOutputPinImpl_Release
(
IPin
*
iface
);
HRESULT
WINAPI
BaseOutputPinImpl_Connect
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BaseOutputPinImpl_ReceiveConnection
(
IPin
*
iface
,
IPin
*
pReceivePin
,
const
AM_MEDIA_TYPE
*
pmt
);
HRESULT
WINAPI
BaseOutputPinImpl_Disconnect
(
IPin
*
iface
);
HRESULT
WINAPI
BaseOutputPinImpl_EndOfStream
(
IPin
*
iface
);
HRESULT
WINAPI
BaseOutputPinImpl_BeginFlush
(
IPin
*
iface
);
HRESULT
WINAPI
BaseOutputPinImpl_EndFlush
(
IPin
*
iface
);
HRESULT
WINAPI
BaseOutputPinImpl_NewSegment
(
IPin
*
iface
,
REFERENCE_TIME
tStart
,
REFERENCE_TIME
tStop
,
double
dRate
);
HRESULT
WINAPI
BaseOutputPinImpl_GetDeliveryBuffer
(
BaseOutputPin
*
This
,
IMediaSample
**
ppSample
,
REFERENCE_TIME
*
tStart
,
REFERENCE_TIME
*
tStop
,
DWORD
dwFlags
);
HRESULT
WINAPI
BaseOutputPinImpl_Deliver
(
BaseOutputPin
*
This
,
IMediaSample
*
pSample
);
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
);
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