다음을 통해 공유


캡처 그래프 작성기를 사용하여 그래프 빌드

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngineMedia Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

이름에도 불구하고 캡처 그래프 작성기는 캡처 그래프뿐만 아니라 다양한 종류의 사용자 지정 필터 그래프를 빌드하는 데 유용합니다. 이 문서에서는 이 개체를 사용하는 방법에 대한 간략한 개요를 제공합니다.

캡처 그래프 작성기는 ICaptureGraphBuilder2 인터페이스를 노출합니다. 먼저 CoCreateInstance 를 호출하여 캡처 그래프 작성기 및 필터 그래프 관리자를 만듭니다. 그런 다음, 다음과 같이 필터 그래프 관리자에 대한 포인터를 사용하여 ICaptureGraphBuilder2::SetFiltergraph 를 호출하여 캡처 그래프 작성기를 초기화합니다.

IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;

// Create the Filter Graph Manager.
HRESULT hr =  CoCreateInstance(CLSID_FilterGraph, NULL,
    CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

if (SUCCEEDED(hr))
{
    // Create the Capture Graph Builder.
    hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, 
        (void **)&pBuilder);
    if (SUCCEEDED(hr))
    {
        pBuilder->SetFiltergraph(pGraph);
    }
};

필터 연결

ICaptureGraphBuilder2::RenderStream 메서드는 체인에서 둘 또는 세 개의 필터를 함께 연결합니다. 일반적으로 메서드는 각 필터에 동일한 형식의 입력 핀 또는 출력 핀이 하나 이상 없을 때 가장 잘 작동합니다. 이 토론은 RenderStream 의 처음 두 매개 변수를 무시하고 마지막 세 개의 매개 변수에 초점을 맞추는 것으로 시작됩니다. 세 번째 매개 변수는 필터(IBaseFilter 인터페이스 포인터) 또는 출력 핀(IPin 인터페이스 포인터)을 지정할 수 있는 IUnknown 포인터입니다. 네 번째 및 다섯 번째 매개 변수는 IBaseFilter 포인터를 지정합니다. RenderStream 메서드는 체인의 세 필터를 모두 연결합니다. 예를 들어 A, BC 가 필터라고 가정합니다. 이제 각 필터에 정확히 하나의 입력 핀과 하나의 출력 핀이 있다고 가정합니다. 다음 호출은 A를 B에 연결한 다음 B를 C에 연결합니다.

'RenderStream(NULL, NULL, A, B, C)'

모든 연결은 "지능적"이므로 필요에 따라 추가 필터가 그래프에 추가됩니다. 자세한 내용은 Intelligent Connect를 참조하세요. 두 개의 필터만 연결하려면 중간 값을 NULL로 설정합니다. 예를 들어 이 호출은 A를 C에 연결합니다.

'RenderStream(NULL, NULL, A, NULL, C)'

메서드를 두 번 호출하여 긴 체인을 만들 수 있습니다.

'RenderStream(NULL, NULL, A, B, C)' 'RenderStream(NULL, NULL, C, D, E)'

마지막 매개 변수가 NULL이면 메서드는 자동으로 기본 렌더러를 찾습니다. 비디오용 Video Renderer와 오디오용 DirectSound 렌더러를 사용합니다. 따라서:

'RenderStream(NULL, NULL, A, NULL, NULL)'

위의 식은 아래의 식과 동일합니다.

'RenderStream(NULL, NULL, A, NULL, R)'

여기서 R 은 적절한 렌더러입니다. 그러나 Video Renderer 대신 비디오 혼합 렌더러 필터를 연결하려면 명시적으로 지정해야 합니다.

핀이 아닌 세 번째 매개 변수에 필터를 지정하는 경우 연결에 사용해야 하는 출력 핀을 지정해야 할 수 있습니다. 이것이 메서드의 처음 두 매개 변수의 목적입니다. 첫 번째 매개 변수는 캡처 필터에만 적용됩니다. 핀 범주를 나타내는 GUID를 지정합니다. 범주의 전체 목록은 고정 속성 집합을 참조하세요. 두 범주는 모든 캡처 필터에 유효합니다.

  • PIN_CATEGORY_CAPTURE
  • PIN_CATEGORY_PREVIEW

캡처 필터가 캡처 및 미리 보기를 위한 별도의 핀을 제공하지 않는 경우 RenderStream 메서드는 스마트 티 필터를 삽입하여 스트림을 캡처 스트림 및 미리 보기 스트림으로 분할합니다. 애플리케이션의 관점에서 모든 캡처 필터를 별도의 핀이 있는 것으로 처리하고 그래프의 기본 토폴로지를 무시할 수 있습니다.

파일 캡처의 경우 캡처 핀을 mux 필터에 연결합니다. 라이브 미리 보기의 경우 미리 보기 핀을 렌더러에 연결합니다. 두 범주를 전환하면 그래프가 파일 캡처 중에 과도한 수의 프레임을 삭제할 수 있습니다. 그러나 그래프가 제대로 연결되면 캡처 스트림에서 처리량을 유지하기 위해 필요에 따라 미리 보기 프레임을 삭제합니다.

다음 예제에서는 두 스트림을 연결하는 방법을 보여 줍니다.

// Capture to file:
pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, NULL, pCapFilter, NULL, pMux);
// Preview:
pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, NULL, pCapFilter, NULL, NULL);

일부 캡처 필터는 PIN_CATEGORY_VBI 표시된 선택 자막도 지원합니다. 파일에 대한 선택 자막을 캡처하려면 이 범주를 mux 필터로 렌더링합니다. 미리 보기 창에서 선택 자막을 보려면 렌더러에 연결합니다.

// Capture to file:
pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL, pCapFilter, NULL, pMux);
// Preview on screen:
pBuilder->RenderStream(&PIN_CATEGORY_VBI, NULL, pCapFilter, NULL, NULL);

RenderStream에 대한 두 번째 매개 변수는 미디어 형식을 식별하며 일반적으로 다음 중 하나입니다.

  • MEDIATYPE_Audio
  • MEDIATYPE_Video
  • DV(MEDIATYPE_Interleaved)

필터의 출력 핀이 기본 미디어 형식의 열거를 지원할 때마다 이 매개 변수를 사용할 수 있습니다. 파일 원본의 경우 캡처 그래프 작성기는 필요한 경우 파서 필터를 자동으로 추가한 다음 파서에서 미디어 형식을 쿼리합니다. (예를 들어 AVI 파일 다시 압축을 참조하세요.) 또한 체인의 마지막 필터에 여러 개의 입력 핀이 있는 경우 메서드는 해당 미디어 형식을 열거하려고 시도합니다. 그러나 모든 필터가 이 기능을 지원하는 것은 아닙니다.

필터 및 핀에서 인터페이스 찾기

그래프를 빌드한 후에는 일반적으로 그래프의 필터 및 핀에 의해 노출되는 다양한 인터페이스를 찾아야 합니다. 예를 들어 캡처 필터는 IAMDroppedFrames 인터페이스를 노출할 수 있지만 필터의 출력 핀은 IAMStreamConfig 인터페이스를 노출할 수 있습니다.

인터페이스를 찾는 가장 간단한 방법은 ICaptureGraphBuilder2::FindInterface 메서드를 사용하는 것입니다. 이 메서드는 원하는 인터페이스를 찾을 때까지 그래프(필터 및 핀)를 안내합니다. 검색의 시작점을 지정할 수 있으며 시작점에서 업스트림 또는 다운스트림으로 필터링하도록 검색을 제한할 수 있습니다.

다음 예제에서는 비디오 미리 보기 핀에서 IAMStreamConfig 인터페이스를 검색합니다.

IAMStreamConfig *pConfig = NULL;
HRESULT hr = pBuild->FindInterface(
    &PIN_CATEGORY_PREVIEW, 
    &MEDIATYPE_Video,
    pVCap, 
    IID_IAMStreamConfig, 
    (void**)&pConfig
);
if (SUCCESSFUL(hr))
{
    /* ... */
    pConfig->Release();
}

참고

필터 또는 핀에서 인터페이스 찾기 항목에서는 ICaptureGraphBuilder2 대신 IGraphBuilder 인터페이스를 사용하는 대체 방법을 보여 줍니다. 사용할 방법은 애플리케이션에 따라 다릅니다. 애플리케이션 이 이미 ICaptureGraphBuilder2 를 사용하여 그래프를 빌드하는 경우 ICaptureGraphBuilder2::FindInterface 가 좋은 방법입니다. 그렇지 않으면 IGraphBuilder 메서드를 사용하는 것이 좋습니다.

 

핀 찾기

일반적으로는 필터에서 개별 핀을 찾아야 할 수 있지만 대부분의 경우 RenderStreamFindInterface 메서드를 사용하면 문제를 줄일 수 있습니다. 필터에서 특정 핀을 찾아야 하는 경우 ICaptureGraphBuilder2::FindPin 도우미 메서드가 유용합니다. 범주, 미디어 유형(비디오 또는 오디오), 방향 및 핀을 연결 해제해야 하는지 여부를 지정합니다.

예를 들어 다음 코드는 캡처 필터에서 연결되지 않은 비디오 미리 보기 핀을 검색합니다.

IPin *pPin = NULL;
hr = pBuild->FindPin(
    pCap,                   // Pointer to the filter to search.
    PINDIR_OUTPUT,          // Search for an output pin.
    &PIN_CATEGORY_PREVIEW,  // Search for a preview pin.
    &MEDIATYPE_Video,       // Search for a video pin.
    TRUE,                   // The pin must be unconnected. 
    0,                      // Return the first matching pin (index 0).
    &pPin);                 // This variable receives the IPin pointer.
if (SUCCESSFUL(hr))
{
    /* ... */
    pPin->Release();
}

비디오 캡처