DirectShow DirectShow 의 사용법 비디오 캡춰 캡춰 그래프의 제어   [목차열람] [주소복사] [슬롯비우기]
캡춰 그래프의 제어
 
Microsoft DirectX 9.0

캡춰 그래프의 제어

필터 그래프 매니저의 IMediaControl 인터페이스에는, 그래프 전체의 실행, 정지, 포즈를 실시하는 메서드가 있다. 그러나, 필터 그래프에 캡춰 스트림과 프리뷰 스트림이 있는 경우는, 2 개의 스트림을 따로 따로 제어할 필요가 있는 것이 많다. 예를 들어, 비디오를 프리뷰 하지만, 캡춰는 하지 않는 것이 있다. 이 처리는,ICaptureGraphBuilder2::ControlStream 메서드를 사용해 실행할 수 있다.

 :  이 메서드는 ASF (Advanced Systems Format) 파일에의 캡춰시에는 동작하지 않는다.

캡춰 스트림의 제어

다음 코드는, 그래프를 실행한 1 초 후에 비디오 캡춰 스트림을 시작 해, 4 초간 실행하도록(듯이) 설정한다.

// 비디오 캡춰 스트림을 제어한다.
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2;  // 임의의 값.
hr = pBuild->ControlStream(
    &PIN_CATEGORY_CAPTURE, // 핀 카테고리.
    &MEDIATYPE_Video,      // 미디어 타입.
    pCap,                  // 캡춰 필터.
    &rtStart, &rtStop,     // 시작 타임 및 종료 타임.
    wStartCookie, wStopCookie  // 시작 이벤트 및 종료 이벤트의 값.
);
pControl->Run();

최초의 인수에는, 핀 카테고리 GUID 로서 제어하는 스트림을 지정한다. 2 번째의 인수에는 미디어 타입을 지정한다. 3 번째의 인수는 캡춰 필터의 포인터이다. 그래프내의 모든 캡춰 스트림을 제어하려면 , 2 번째와 3 번째의 인수를 NULL 로 설정한다.

다음의 2 개의 파라미터에는, 그래프의 실행 시작시에 대립되어, 스트림의 시작 타임과 종료 타임을 지정한다. 그래프를 실행하기 위해(때문에),IMediaControl::Run 를 호출한다. 그래프를 실행할 때까지,ControlStream 메서드를 호출해도 효과는 없다. 그래프가 이미 실행되고 있는 경우, 설정은 곧바로 반영된다.

마지막 2 개의 파라미터는, 스트림의 시작시와 정지시에 이벤트 통지를 받을 때 사용한다. 이 메서드를 사용해 제어하는 스트림 마다, 필터 그래프는 이벤트의 페어를 송신한다. 스트림의 시작시에는 EC_STREAM_CONTROL_STARTED , 스트림의 정지시에는 EC_STREAM_CONTROL_STOPPED 를 송신한다. wStartCookiewStopCookie 의 값이 2 번째의 이벤트 파라미터로서 사용된다. 따라서, 시작 이벤트의 lParam2wStartCookie 에 동일하고, 종료 이벤트의 lParam2wStopCookie 에 동일하다. 다음 코드는, 이러한 이벤트를 받는 방법을 나타내고 있다.

while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))
{
    switch (evCode)
    {
    case EC_STREAM_CONTROL_STARTED: 
    // param2 == wStartCookie
    break;

    case EC_STREAM_CONTROL_STOPPED: 
    // param2 == wStopCookie
    break;
    
    } 
    pEvent->FreeEventParams(evCode, param1, param2);
}

ControlStream 메서드는 시작 타임과 종료 타임에 특수한 값을 정의한다.

  시작 종료
MAXLONGLONG 이 스트림을 시작 하지 않는다. 그래프가 정지할 때까지 정지하지 않는다.
NULL 그래프가 실행되자마자 시작 한다. 곧바로 정지한다.

예를 들어, 다음 코드는 캡춰 스트림을 곧바로 정지한다.

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
    0, 0,     // 시작 타임 및 종료 타임.
    wStartCookie, wStopCookie); 

캡춰 스트림을 정지해, 다음에 재개할 수 있지만, 타임 스탬프에는 갭이 발생한다. 재생시에는, 갭의 사이, 비디오는 정지한 것처럼 보인다 (파일 포맷에 의해 다르다).

프리뷰 스트림의 제어

프리뷰 핀을 제어하려면 ,ControlStream 를 호출하지만, 최초의 파라미터는 PIN_CATEGORY_PREVIEW 로 설정한다. 이 경우, PIN_CATEGORY_CAPTURE 를 지정했을 때 것과 같이 동작하지만, 프리뷰 프레임에는 타임 스탬프가 없기 때문에, 기준 타임을 사용해 시작과 정지는 지정할 수 없다. 따라서, NULL 또는 MAXLONGLONG 를 사용할 필요가 있다. 프리뷰 스트림을 시작 하려면 , NULL 를 사용한다.

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    NULL,    // 곧바로 시작 한다.
    0,       // (여기에서는 무관계. )
    wStartCookie, wStopCookie); 

프리뷰 스트림을 정지하려면 , MAXLONGLONG 를 사용한다.

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    0,               // (여기에서는 무관계. )
    MAXLONGLONG,     // 곧바로 정지한다.
    wStartCookie, wStopCookie); 

프리뷰 스트림을 캡춰 필터의 프리뷰 핀으로부터 얻어온다인가, 스마트티필터로부터 얻어온다인가는 문제는 아니다. ControlStream 메서드는 어디라도 동작한다.

그러나, 비디오 포트 핀의 경우, 메서드는 실패한다. 그 경우, 비디오 윈도우를 비표시로 하는 방법이 있다. 그래프에 IVideoWindow 를 문의해IVideoWindow::put_Visible 메서드를 사용해 윈도우의 표시 또는 비표시를 바꾼다.

// 비디오 윈도우를 비표시로 한다.
IVideoWindow *pVidWin = 0;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**) &pVidWin);
if (SUCCEEDED(hr))
{
    pVidWin->put_Visible(OAFALSE);
    pVidWin->Release();
}

또, 그래프를 실행하기 전에 값 OAFALSE 를 사용해 IVideoWindow::put_AutoShow 를 호출했을 경우, 그 밖에 지정할 때까지, 비디오 렌더러 필터는 윈도우를 비표시로 한다. 디폴트에서는, 그래프를 실행 하면, 비디오 렌더러는 윈도우를 표시한다.

스트림 제어에 대한 주의점

그래프가 실행될 때, 핀의 디폴트 동작은 샘플의 송신이다. 예를 들어, PIN_CATEGORY_PREVIEW 은 아니고 PIN_CATEGORY_CAPTURE 를 사용해 ControlStream 를 호출하면 한다. 그래프를 실행 하면, 프리뷰 스트림은 곧바로 실행되어 캡춰 스트림은 ControlStream 로 지정한 타임에 실행된다.

복수의 스트림을 캡춰 해, Mux 필터에 송신하는 경우 (예를 들어, 오디오와 비디오를 AVI 파일에 캡춰 하는 경우), 양쪽 모두의 스트림을 직렬식에 제어하는 것. 그렇게 하지 않으면 Mux 필터는 2 개의 스트림을 인터리브 하려고 해, 한편의 스트림의 도착을 기다려 블록 되는 일이 있다. 그래프를 실행하기 전에, 모든 캡춰 스트림에 같은 시작 타임과 정지 타임을 설정하는 것.

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, 
    NULL, NULL,       // 모든 캡춰 스트림.
    &rtStart, rtStop, 
    wStartCookie, wStopCookie); 

ControlStream 메서드는 내부적으로 IAMStreamControl 인터페이스를 사용한다. 이 인터페이스는, 캡춰 필터, 스마트티필터 (존재하는 경우), 및 경우에 따라서는 Mux 필터의 핀으로 공개된다. ControlStream 를 호출하는 대신에, 이 인터페이스를 직접 사용할 수 있다. 다만, 특히 이점은 없다.

↑TOP