Currently I'm working on a DirectShow based application for configuring TV capture cards. It's supposed to work with most of the capture cards out there, so it has to be as generic as possible.
Since most capture card manufacturers seem to come up with different ways of configuration, my application will try to analyse the related filters and their pins. One common is checking if a certain pin can be connected to a renderer directly, or it needs an encoder/mux first.
Note: I am using the DirectShow .NET library with VB.NET, but you can answer in C# or C++ if you like.
I tried checking if the output pin accepts a certain AMMediaType
with the following function:
Private Function Check1(filter As IBaseFilter, type As AMMediaType) As Boolean
Dim enumPins As IEnumPins = Nothing
If filter.EnumPins(enumPins) = 0 Then
Dim pin(0) As IPin
While (enumPins.Next(1, pin, Nothing) = 0)
Dim accepted As Boolean = (pin(0).QueryAccept(type) = 0)
Marshal.ReleaseComObject(pin(0))
If accepted Then Return True
End While
End If
Return False
End Function
This function always returns False
. After some debugging I found out that QueryAccept
always returns -2147467259
. The documentation does not mention such return value. After some more investigation, I found out QueryAccept
is used for proposing a new MediaType, so I assume QueryAccept only works when the calling pin is already connected. Read more here.
I can check if a certain AMMediaType
is preferred by the output pin using the function below:
Private Function Check2(filter As IBaseFilter, type As AMMediaType) As Boolean
Dim enumPins As IEnumPins = Nothing
If filter.EnumPins(enumPins) = 0 Then
Dim pin(0) As IPin
While (enumPins.Next(1, pin, Nothing) = 0)
Dim enumMediaTypes As IEnumMediaTypes = Nothing
If pin(0).EnumMediaTypes(enumMediaTypes) = 0 Then
Dim mediaType(0) As AMMediaType
While (enumMediaTypes.Next(1, mediaType, Nothing) = 0)
Dim equals As Boolean = (type Is Nothing OrElse
(type.majorType = Nothing OrElse mediaType(0).majorType = type.majorType) AndAlso
(type.subType = Nothing OrElse mediaType(0).subType = type.subType) AndAlso
(type.formatType = Nothing OrElse mediaType(0).formatType = type.formatType))
DsUtils.FreeAMMediaType(mediaType(0))
If equals Then
Return True
End If
End While
End If
End While
End If
Return False
End Function
By enumerating EnumMediaTypes
, I can determine if a certain AMMediaType
is listed as preferred. This, however, does not assure me that a connection is possible. Often there are types that are not contained by this enumeration, but can still be used to connect. Sometimes this enumeration is empty.
What I'm searching for is a way to determine if a filter can be connected to another filter directly, or it should connect to an encoder/mux first. Does someone know how I can achieve this?
Note: Simply connecting the filters and using the return value to determine if it was succesful, is not an option. In my experience, ICaptureGraphBuilder::RenderStream often returns S_OK
while no connection was made. For example, try using MediaType.AnalogVideo
while there is no analog video pin.