В настоящее время я работаю над приложением на основе DirectShow для настройки карт захвата ТВ. Предполагается, что он работает с большинством карт захвата, поэтому он должен быть как можно более универсальным.
Поскольку большинство производителей карт захвата предлагают разные способы конфигурации, мое приложение попытается проанализировать соответствующие фильтры и их контакты. Одним из распространенных является проверка того, может ли определенный вывод быть подключен к рендереру напрямую, или ему сначала нужен кодировщик/мультиплексор.
Примечание. Я использую библиотеку DirectShow .NET с VB.NET, но вы можете ответить на С# или С++, если хотите.
Я попытался проверить, принимает ли выходной контакт определенный AMMediaType
со следующей функцией:
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
Эта функция всегда возвращает False
. После некоторой отладки я обнаружил, что QueryAccept
всегда возвращает -2147467259
. Документация не упоминать такое возвращаемое значение. После еще одного исследования я обнаружил, что QueryAccept
используется для предложения нового MediaType, поэтому я предполагаю, что QueryAccept работает только тогда, когда вызывающий контакт уже подключен. Подробнее читайте здесь .
Я могу проверить, предпочитает ли определенный AMMediaType
выходной контакт, используя функцию ниже:
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
Перечисляя EnumMediaTypes
, я могу определить, указан ли определенный AMMediaType
как предпочтительный. Это, однако, не гарантирует мне, что связь возможна. Часто встречаются типы, которые не входят в это перечисление, но все же могут быть использованы для подключения. Иногда это перечисление пусто.
То, что я ищу, - это способ определить, может ли фильтр быть подключен к другому фильтру напрямую, или он должен сначала подключиться к кодеру/мультиплексору. Кто-нибудь знает, как я могу этого добиться?
Примечание. Просто подключить фильтры и использовать возвращаемое значение, чтобы определить, было ли оно успешным, нельзя. По моему опыту, ICaptureGraphBuilder:: RenderStream часто возвращает S_OK
, хотя соединение не установлено. Например, попробуйте использовать MediaType.AnalogVideo
, пока нет аналогового видеовывода.