DirectShow DirectShow 에 대해 동적 그래프 생성 동적재접속   [목차열람] [주소복사] [슬롯비우기]
동적재접속
 
Microsoft DirectX 9.0

동적재접속

많은 DirectShow 필터에서는, 그래프가 액티브하게 데이터를 스트리밍 하고 있는 동안은 핀을 재접속할 수 없다. 애플리케이션은, 핀을 재접속하기 전에 그래프를 정지할 필요가 있다. 다만, 일부의 필터에서는, 그래프의 실행중의 핀의 재접속을 지원 하고 있다. 이 처리를 "동적재접속" 이라고 부른다. 이 처리는, 애플리케이션 또는 그래프내의 필터에 의해 실행된다.

예로서 다음과 같은 그래프를 생각해 본다.

동적 그래프 생성

동적재접속의 시나리오의 1 개로서 그래프의 실행중에, 그래프로부터 필터 2 를 삭제해, 다른 필터에 치환하는 경우가 있다. 이 시나리오가 기능하려면 , 다음의 조건을 채울 필요가 있다.

동적재접속은, 다음과 같은 순서로 행해진다.

  1. 핀 A 로부터의 데이터 스트림을 블록 한다.
  2. 보통, 새로운 중간 필터를 개입시켜, 핀 A 와 핀 D 를 재접속한다.
  3. 플로우가 재개하도록(듯이), 핀 A 의 블록을 해제한다.

순서 1. 데이터 스트림의 블록

데이터 스트림을 블록 하기 위해서, 핀 A 로 IPinFlowControl::Block 를 호출한다. 이 메서드는, 비동기적으로도, 동기적으로도 호출할 수가 있다. 이 메서드를 "비동기적" 으로 호출하려면 , Win32 이벤트 개체를 생성 해, 이벤트 핸들을 Block 메서드에 건네준다. 이 메서드는 즉시 돌아온다. WaitForSingleObject 와 같은 함수를 사용해, 이벤트가 신호 상태가 될 때까지 대기한다. 핀은, 데이터 플로우를 블록 하면, 이벤트를 송신한다. 이하에 예를 나타낸다.

// 이벤트를 생성 한다
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
    // 데이터 플로우를 블록 한다.
    hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent); 
    if (SUCCEEDED(hr))
    {
        // 핀이 완료할 때까지 대기한다.
        DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
    }
}

이 메서드를 "동기적" 으로 호출하려면 , 이벤트 핸들 대신에 NULL 값을 건네주는 것만으로 좋다. 이것으로, 메서드는 처리가 완료할 때까지 블록 한다. 핀이 새로운 샘플을 출력할 준비를 할 수 있을 때까지, 이 처리는 행해지지 않을 가능성이 있다. 필터가 포즈 상태인 경우, 임의의 길이의 시간이 걸릴 가능성이 있다. 그 때문에, 애플리케이션의 메인 thread로부터, 동기적으로 호출해서는 안 된다. 워커 thread를 사용하는지, 이 메서드를 비동기적으로 호출하는 것.

순서 2. 핀의 재접속

핀을 재접속하기 위해서, 필터 그래프 매니저는 IGraphConfig 인터페이스를 조회해,IGraphConfig::Reconnect 또는 IGraphConfig::Reconfigure 의 어느쪽이든을 호출한다. Reconnect 메서드의 사용법은 단순하다. 이 메서드는 다음의 처리를 실시한다.

Reconnect 메서드에는, 핀 접속의 미디어 타입 및 사용하는 중간 필터를 지정하기 위해서 사용할 수 있는 옵션의 파라미터가 몇개인가 있다. 이하에 예를 나타낸다.

pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
pConfig->Reconnect(
    pPinA,      // 이 출력 핀을...
    pPinD,      // ... 이 입력 핀에 재접속한다.
    pMediaType, // 이 미디어 타입을 사용한다.
    pNewFilter, // 이 필터를 개입시켜 접속한다.
    NULL, 
    0);     

더 자세한 정보는, 레퍼런스 페이지를 참조할것. Reconnect 메서드의 유연성이 충분하지 않는 경우는,Reconfigure 메서드를 사용할 수 있다. 이 메서드는, 애플리케이션 정의의 콜백 메서드를 사용해 핀을 재접속한다. 이 메서드를 사용하려면 , 애플리케이션으로 IGraphConfigCallback 인터페이스를 처리 한다.

Reconfigure 를 호출하기 전에, 전에 설명한 것처럼, 출력 핀으로부터의 데이터 플로우를 블록 한다. 다음에, 재접속하고 있는 그래프의 섹션으로 보류 상태가 되어 있는 데이터를, 다음과 같이 푸쉬 한다.

  1. 재접속 체인의 가장 다운 스트림의 입력 핀 (예에서는 핀 D)으로 IPinConnection::NotifyEndOfStream 를 호출한다. 핸들을 Win32 이벤트에 건네준다.
  2. 데이터 플로우를 블록 한 출력 핀의 곧 다음에 있는 다운 스트림의 입력 핀으로 IPin::EndOfStream 를 호출한다. 이 예에서는, 데이터 플로우는 핀 A 로 블록 되고 있으므로, 핀 B 로 EndOfStream 를 호출한다.
  3. 이벤트가 통지필 상태가 되는 것을 기다린다. 입력 핀 (핀 D)은, 엔드 오브 스트림 통지를 수신 하면, 이벤트를 송신한다. 이것은, 핀간에 데이터의 수수가 없는 것, 및 호출측이 안전하게 핀을 재접속할 수 있는 것을 나타낸다.

IGraphConfig::Reconnect 메서드는 자동적으로 전의 순서를 처리한다. 이러한 순서를 수동으로 실행할 필요가 있는 것은,Reconfigure 메서드를 사용하는 경우 뿐이다.

그래프내에서 데이터가 푸쉬 된 후,Reconfigure 를 호출해,IGraphConfigCallback 콜백 인터페이스의 포인터를 건네준다. 필터 그래프 매니저는, 지정된 IGraphConfigCallback::Reconfigure 메서드를 호출한다.

순서 3. 데이터 플로우의 블록 해제

핀을 재접속하면 최초의 파라미터에 0 을 건네주어 IPinFlowControl::Block 을 호출해, 데이터 플로우의 블록을 해제한다.

  필터가 동적재접속을 실시하는 경우, 몇개의 thread의 문제에 주의해야 한다. 필터 그래프 매니저가 필터를 정지하려고 했을 경우, 그래프는 필터가 정지하는 것을 기다려, 동시에 필터는 데이터가 그래프에 푸쉬 되는 것을 기다리므로, 데드 록이 발생하는 일이 있다. 이러한 데드 록을 회피하기 위해서, 여기서 설명한 메서드의 몇개인가는 Win32 이벤트에의 핸들을 사용한다. 필터는, 필터 그래프 매니저가 필터를 정지하려고 하면 이벤트를 송신한다. 더 자세한 정보는, 「IGraphConfig 인터페이스」 및 「IPinConnection 인터페이스」를 참조할것.

↑TOP