2012-11-29 6 views
0

현재 TV 캡처 카드 구성을위한 DirectShow 기반 응용 프로그램에서 작업 중입니다. 이 카드는 대부분의 캡처 카드로 작동하기 때문에 가능한 한 포괄적이어야합니다.핀을 연결할 수 있는지 확인하는 방법은 무엇입니까?

대부분의 캡처 카드 제조업체는 구성 방법이 다르기 때문에 내 응용 프로그램은 관련 필터와 핀을 분석하려고합니다. 하나의 공통점은 특정 핀을 렌더러에 직접 연결할 수 있는지 또는 먼저 인코더/멀티플렉서가 필요한지 여부를 확인하는 것입니다.

참고 : VB.net에서는 DirectShow .NET 라이브러리를 사용하고 있지만 C# 또는 C++로 대답 할 수 있습니다.

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를 반환 출력 핀은 다음과 같은 기능을 특정 AMMediaType을 받아들이는 경우

나는 확인했습니다. 일부 디버깅 후 QueryAccept은 항상 -2147467259을 반환한다는 것을 알게되었습니다. The documentation에는 이러한 반환 값이 언급되어 있지 않습니다. 좀 더 조사한 후에, 새로운 MediaType을 제안하는 데 QueryAccept이 사용됨을 알았습니다. 따라서 QueryAccept이 호출 핀이 이미 연결되어있을 때만 작동한다고 가정합니다. Read more here. 특정 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을 열거하여, I는 바람직한로서 특정 AMMediaType이 표시되는지를 결정할 수있다. 그러나 이것은 연결이 가능하다는 것을 보장하지 않습니다. 종종이 열거 형에 포함되지 않지만 연결할 수있는 형식이 있습니다. 때때로이 열거 형은 비어 있습니다.

내가 찾고있는 것은 필터를 다른 필터에 직접 연결할 수 있는지 또는 인코더/멀티플렉서에 먼저 연결해야 하는지를 결정하는 방법입니다. 누군가가 이것을 어떻게 달성 할 수 있는지 알고 있습니까?

참고 : 단순히 필터를 연결하고 반환 값을 사용하여 성공했는지 여부를 확인하는 것은 옵션이 아닙니다. 내 경험상 ICaptureGraphBuilder::RenderStream은 연결이없는 경우 종종 S_OK을 반환합니다. 예를 들어, 아날로그 비디오 핀이없는 동안 MediaType.AnalogVideo을 사용해보십시오.

+1

핀이 직접 연결될 수 있는지 확인하려면 렌더러에서 소스 필터와 입력 핀의 출력 핀을 가져 와서 [IPin :: Connect] (http://msdn.microsoft .com/de-de/library/windows/desktop/dd390420 (v = vs.85) .aspx). RGB24 또는 YUY2 또는 NV12와 같은 원시 비디오 유형 인 경우 소스는 비디오 렌더에 직접 연결 만 할 수 있습니다. 그러나 종종 그들 사이에 디코더가 필요합니다. TV 카드의 경우 MPEG2 또는 h264 디코더가됩니다. – CPlusSharp

+0

@CPlusSharp : IPin :: Connect를 시도했지만 어떤 경우에는 예상대로 작동하지 않았습니다. 그러나 이것이 IGraphBuilder :: Connect를 사용하게 만들었습니다. 내 대답을 보라. –

답변

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 
+1

IGraphBuilder :: Connect를 사용하는 경우 DirectShow는 [Intelligent Connect] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd390342(v=vs.85).aspx)를 사용하고 중간 필터! 그게 내 첫 코멘트에서 의미. 이 방법을 사용하면 연결을 끊은 후에 현재 사용하지 않는 필터 (중간 필터)를 제거해야합니다. – CPlusSharp

1

확인하십시오. 그러나 "일반적인"연결 방법 IGraphBuilder::Connect에는 인텔리전트 연결이 포함되어 있으며 중간에 추가 필터를 삽입하기 시작합니다. 이것을 원하지 않으면 IGraphBuilder::ConnectDirect 방법이 있습니다. 직접 으로 전화하지 마십시오. 제대로 작동 할 수도 있지만 직접 호출하지 않아도됩니다. 대신 ConnectDirect가 대신 호출합니다.

ConnectDirect의 경우 미디어 유형도 제공해야합니다.널 미디어 유형이 제대로 작동하지 않거나 출력 핀에서 열거 된 유형의 미디어 유형을 사용해 볼 수 있습니다. 기본적으로 이것은 기본적으로 기본 동작입니다. 출력 핀은 미디어 유형을 인수로 제공하려고 시도하고 (null이 아닌 경우) 자체적으로 시도한 다음 피어 입력 핀에서 열거 된 유형을 시도한 다음 Intelligent Connect가 작동하기 시작합니다 (ConnectDirect 호출).

모두 RenderStream 및 친구들은 위에서 언급 한 래퍼입니다.

또한 -21474672590x80004005E_FAIL "Unspecified error"입니다.

관련 문제