0

現在、TVキャプチャカードを構成するためのDirectShowベースのアプリケーションに取り組んでいます。そこにあるほとんどのキャプチャカードで動作するはずなので、可能な限り一般的である必要があります。

ほとんどのキャプチャカードメーカーはさまざまな構成方法を考え出しているようですので、私のアプリケーションは関連するフィルターとそのピンを分析しようとします。一般的な方法の1つは、特定のピンをレンダラーに直接接続できるかどうか、または最初にエンコーダー/マルチプレクサが必要かどうかを確認することです。

:私はVB.NETでDirectShow .NETライブラリを使用していますが、必要に応じてC#またはC++で回答できます。

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アナログビデオピンがない状態で使用してみてください。

4

2 に答える 2

1

ピンを接続できるかどうかを確認するには、ピンを接続してみる必要があります。ただし、「通常の」接続方法には、中央に追加のフィルターを挿入しようとする、IGraphBuilder::Connectいわゆるインテリジェントコネクトが含まれます。これが必要ない場合は、IGraphBuilder::ConnectDirect方法があります。直接呼び出さないでくださいIPin::Connect。正常に機能する可能性はありますが、直接呼び出されることは想定されていません。代わりに、ConnectDirectから呼び出されます。

ConnectDirectの場合は、メディアタイプも指定する必要があることに注意してください。ヌルメディアタイプが機能する場合があります。または、出力ピンに列挙されているメディアタイプを試してみることもできます。基本的に、これは最初のデフォルトの動作です。出力ピンは引数として提供されたメディアタイプを試し(nullでない場合)、それ自体を試し、次にピア入力ピンによって列挙されたメディアタイプを試し、Intelligent Connectが機能し始めます(そうでない場合) ConnectDirect呼び出し)。

すべてRenderStreamと友人は、言及された上にラッパーです。

また、「不特定のエラー」-2147467259です。0x80004005 E_FAIL

于 2012-11-30T07:41:00.430 に答える
0

ICaptureGraphBuilder :: RenderStreamの代わりに、 IGraphBuilder :: Connectを使用することになりましたが、接続が可能かどうかを確認するためだけです。フィルタを接続した後、次の関数はすぐにフィルタを切断し、HRESULTを使用して接続が成功したかどうかを判断します。

Private Function Check3(graph As IGraphBuilder, filterOut As IBaseFilter, filterIn As IBaseFilter, type As AMMediaType) As Boolean
  Dim result As Boolean

  ' Enumerate output pins
  Dim enumPinsOut As IEnumPins = Nothing
  If filterOut.EnumPins(enumPinsOut) = 0 Then
    Dim pinOut(0) As IPin
    While enumPinsOut.Next(1, pinOut, Nothing) = 0

      ' Enumerate output media types
      Dim enumMediaTypes As IEnumMediaTypes = Nothing
      If pinOut(0).EnumMediaTypes(enumMediaTypes) = 0 Then
        Dim mediaType(0) As AMMediaType
        While enumMediaTypes.Next(1, mediaType, Nothing) = 0

          ' Compare media types
          If type Is Nothing OrElse
            (type.majorType = Nothing OrElse type.majorType = mediaType(0).majorType) AndAlso
            (type.subType = Nothing OrElse type.subType = mediaType(0).subType) AndAlso
            (type.formatType = Nothing OrElse type.formatType = mediaType(0).formatType) Then

            ' Enumerate input pins
            Dim enumPinsIn As IEnumPins = Nothing
            If filterIn.EnumPins(enumPinsIn) = 0 Then
              Dim pinIn(0) As IPin
              While enumPinsIn.Next(1, pinIn, Nothing) = 0

                ' Evaluate connection return value
                Dim hr As Integer = graph.Connect(pinOut(0), pinIn(0))
                graph.Disconnect(pinOut(0))
                result = (hr = 0)
                If result = False Then Console.WriteLine(DsError.GetErrorText(hr))

                Marshal.ReleaseComObject(pinIn(0))
                If result = True Then Exit While
              End While
            End If
          End If

          DsUtils.FreeAMMediaType(mediaType(0))
          If result = True Then Exit While
        End While
      End If

      Marshal.ReleaseComObject(pinOut(0))
      If result = True Then Exit While
    End While
  End If

  Return result
End Function
于 2012-11-29T13:40:03.873 に答える