동적 다시 연결
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine 및 오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]
대부분의 DirectShow 필터에서 그래프가 데이터를 적극적으로 스트리밍하는 동안에는 핀을 다시 연결할 수 없습니다. 애플리케이션은 핀을 다시 연결하기 전에 그래프를 중지해야 합니다. 그러나 그래프가 실행되는 동안 일부 필터는 핀 다시 연결을 지원합니다. 이 프로세스를 동적 다시 연결이라고 합니다. 이 작업은 애플리케이션 또는 그래프의 필터를 통해 수행할 수 있습니다.
예를 들어 다음 그림에서 그래프를 고려합니다.
동적 다시 연결의 한 가지 시나리오는 그래프가 실행되는 동안 그래프에서 필터 2를 제거하고 다른 필터로 바꾸는 것입니다. 이 시나리오가 작동하려면 다음이 true여야 합니다.
- 필터 3(핀 D)의 입력 핀은 IPinConnection 인터페이스를 지원해야 합니다. 이 인터페이스를 사용하면 필터를 중지하지 않고 핀을 다시 연결할 수 있습니다.
- 필터 1(핀 A)의 출력 핀은 다시 연결이 발생하는 동안 미디어 데이터의 흐름을 차단할 수 있어야 합니다. 다시 연결하는 동안 핀 A와 핀 D 사이를 이동할 수 있는 데이터는 없습니다. 일반적으로 이는 출력 핀이 IPinFlowControl 인터페이스를 지원해야 한다는 것을 의미합니다. 그러나 필터 1이 다시 연결을 시작하는 필터인 경우 자체 데이터 흐름을 차단하는 몇 가지 내부 메커니즘이 있을 수 있습니다.
동적 다시 연결에는 다음 단계가 포함됩니다.
- 핀 A에서 데이터 스트림을 차단합니다.
- 새 중간 필터를 통해 핀 A를 다시 연결하여 D를 고정합니다.
- 데이터가 다시 흐르기 시작하도록 핀 A의 차단을 해제합니다.
1단계. 데이터 스트림 차단
데이터 스트림을 차단하려면 핀 A에서 IPinFlowControl::Block 을 호출합니다. 이 메서드는 비동기적으로 또는 동기적으로 호출할 수 있습니다. 메서드를 비동기적으로 호출하려면 Win32 이벤트 개체를 만들고 이벤트 핸들을 Block 메서드에 전달합니다. 메서드는 즉시 반환됩니다. WaitForSingleObject와 같은 함수를 사용하여 이벤트가 신호를 받을 때까지 기다립니다. 핀은 데이터 흐름을 차단했을 때 이벤트를 신호로 보냅니다. 예를 들면 다음과 같습니다.
// Create an event
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
// Block the data flow.
hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent);
if (SUCCEEDED(hr))
{
// Wait for the pin to finish.
DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
}
}
메서드를 동기적으로 호출하려면 이벤트 핸들 대신 NULL 값을 전달하면 됩니다. 이제 메서드는 작업이 완료될 때까지 차단됩니다. 핀이 새 샘플을 제공할 준비가 될 때까지는 이 문제가 발생하지 않을 수 있습니다. 필터가 일시 중지되면 임의 시간이 걸릴 수 있습니다. 따라서 기본 애플리케이션 스레드에서 동기 호출을 수행하지 마세요. 작업자 스레드를 사용하거나 메서드를 비동기적으로 호출합니다.
2단계. 핀 다시 연결
핀을 다시 연결하려면 IGraphConfig 인터페이스에 대한 Filter Graph Manager를 쿼리하고 IGraphConfig::Reconnect 또는 IGraphConfig::Reconfigure를 호출합니다. 다시 연결 메서드는 사용하기가 더 간단합니다. 다음을 수행합니다.
- 중간 필터(예제의 필터 2)를 중지하고 그래프에서 제거합니다.
- 필요한 경우 새 중간 필터를 추가합니다.
- 모든 핀을 연결합니다.
- 그래프의 상태와 일치하도록 새 필터를 일시 중지하거나 실행합니다.
Reconnect 메서드에는 핀 연결의 미디어 형식과 사용할 중간 필터를 지정하는 데 사용할 수 있는 몇 가지 선택적 매개 변수가 있습니다. 예를 들면 다음과 같습니다.
pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
pConfig->Reconnect(
pPinA, // Reconnect this output pin...
pPinD, // ... to this input pin.
pMediaType, // Use this media type.
pNewFilter, // Connect them through this filter.
NULL,
0);
자세한 내용은 참조 페이지를 참조하세요. Reconnect 메서드가 충분히 유연하지 않은 경우 애플리케이션 정의 콜백 메서드를 호출하여 핀을 다시 연결하는 Reconfigure 메서드를 사용할 수 있습니다. 이 메서드를 사용하려면 애플리케이션에서 IGraphConfigCallback 인터페이스를 구현합니다.
Reconfigure를 호출하기 전에 앞에서 설명한 대로 출력 핀에서 데이터 흐름을 차단합니다. 그런 다음, 다음과 같이 다시 연결하려는 그래프의 섹션에서 보류 중인 모든 데이터를 푸시합니다.
- 다시 연결 체인의 입력 핀 가장 먼 다운스트림에서 IPinConnection::NotifyEndOfStream 을 호출합니다(예제의 핀 D). Win32 이벤트에 핸들을 전달합니다.
- 데이터 흐름을 차단한 출력 핀에서 즉시 다운스트림되는 입력 핀에서 IPin::EndOfStream 을 호출합니다. (이 예제에서는 핀 A에서 데이터 흐름이 차단되었으므로 핀 B에서 EndOfStream 을 호출합니다.)
- 이벤트가 신호를 받을 때까지 기다립니다. 입력 핀(핀 D)은 스트림 종료 알림을 받을 때 이벤트를 신호로 보냅니다. 이는 핀 사이를 이동하는 데이터가 없으며 호출자가 핀을 안전하게 다시 연결할 수 있음을 나타냅니다.
IGraphConfig::Reconnect 메서드는 이전 단계를 자동으로 처리합니다. Reconfigure 메서드를 사용하는 경우에만 이러한 단계를 수행해야 합니다.
데이터가 그래프를 통해 푸시된 후 Reconfigure 를 호출하고 IGraphConfigCallback 콜백 인터페이스에 포인터를 전달합니다. Filter Graph Manager는 제공한 IGraphConfigCallback::Reconfigure 메서드를 호출합니다.
3단계: Data Flow 차단 해제
핀을 다시 연결한 후 첫 번째 매개 변수에 대해 값이 0인 IPinFlowControl::Block 을 호출하여 데이터 흐름을 차단 해제합니다.
참고
필터에서 동적 다시 연결을 수행하는 경우 알아야 할 몇 가지 스레딩 문제가 있습니다. 필터 그래프 관리자가 필터를 중지하려고 하면 그래프가 필터가 중지될 때까지 대기하는 동시에 필터가 그래프를 통해 데이터가 푸시될 때까지 대기할 수 있으므로 교착 상태가 될 수 있습니다. 가능한 교착 상태를 방지하기 위해 이 섹션에 설명된 일부 메서드는 Win32 이벤트에 대한 핸들을 사용합니다. 필터 그래프 관리자가 필터를 중지하려고 하면 필터가 이벤트에 신호를 보내야 합니다. 자세한 내용은 IGraphConfig 및 IPinConnection을 참조하세요.
관련 항목