DirectShow 퍼스트 스텝 가이드 파일의 재생법   [목차열람] [주소복사] [슬롯비우기]
파일의 재생법
 
Microsoft DirectX 9.0

파일의 재생법

여기에서는, DirectShow 프로그래밍의 일례를 나타낸다. 오디오 또는 비디오 파일을 재생하는 간단한 콘솔 프로그램이 나타나고 있다. 이 프로그램은 그저 몇 줄기이지만, DirectShow 프로그래밍의 가능성의 일단을 현저하게 가리키고 있다.

DirectShow 애플리케이션 프로그래밍의 개요」로 설명하고 있도록(듯이),DirectShow 애플리케이션이 실행하는 기본적인 순서는 항상 같다.

  1. 필터 그래프 매니저의 인스턴스를 생성 한다.
  2. 필터 그래프 매니저를 사용해 필터 그래프를 생성 한다.
  3. 그래프를 실행해, 데이터를 필터로 처리한다.

우선 최초로,CoInitialize 를 호출해 COM 라이브러리를 초기화한다.

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
    // 여기에 에러 처리 코드를 추가한다.  이 예에서는 알기 쉽게 하기 위해서 생략 하고 있다.
}

설명을 간단하게 하기 위해서, 이 예에서는 반환값을 무시하고 있지만, 보통은 메서드의 호출로부터의 HRESULT 값을 체크할 필요가 있다.

다음에,CoCreateInstance 를 호출해 필터 그래프 매니저를 생성 한다.

IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, 
    CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **) &pGraph);

여기에 나타나고 있도록(듯이), 클래스 식별자 (CLSID)는 CLSID_FilterGraph 이다. 필터 그래프 매니저는 인 프로세스 DLL 로서 제공되므로, 실행 문맥은 CLSCTX_INPROC_SERVER 이다. DirectShow 에서는 프리 thread 모델을 지원 하고 있으므로, COINIT_MULTITHREADED 플래그를 지정해 CoInitializeEx 를 호출할 수도 있다.

CoCreateInstance 를 호출하면 IGraphBuilder 인터페이스가 반환된다. 이 인터페이스에 필터 그래프를 생성하기 위한 대부분의 메서드가 포함되어 있다. 이 예에서는, 이외에 2 개의 인터페이스가 필요하다.

이러한 인터페이스는 모두 필터 그래프 매니저에 의해 공개된다. 이러한 인터페이스를 조회하려면 , 돌려주어진 IGraphBuilder 포인터를 사용한다.

IMediaControl *pControl;
IMediaEvent   *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pEvent);

이것으로, 필터 그래프를 생성 할 수 있다. 파일의 재생에 대해서는, 단일의 메서드의 호출로 행해진다.

hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);

IGraphBuilder::RenderFile 메서드는, 지정된 파일을 재생할 수 있는 필터 그래프를 생성 한다. 최초의 파라미터는, 와이드 문자 (2 바이트)의 캐릭터 라인으로 나타내진 파일명이다. 2 번째의 파라미터는 예약이 끝난 상태로, NULL 이어야 한다.

이 메서드는, 지정된 파일이 존재하지 않는 경우, 또는 파일 포맷이 인식되지 않는 경우, 실패하는 일이 있다. 여기에서는, 메서드가 성공했다고 가정해, 필터 그래프로 재생의 준비를 할 수 있었다고 한다. 그래프를 실행하려면 ,IMediaControl::Run 메서드를 호출한다.

hr = pControl->Run();

필터 그래프를 실행 하면, 데이터는 필터내에서 처리되어 비디오 및 오디오로서 렌더링 된다. 재생은 다른 thread로 계속된다. IMediaEvent::WaitForCompletion 메서드를 호출해, 재생이 완료할 때까지 대기할 수 있다.

long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);

이 메서드는, 파일의 재생이 종료할 때까지, 또는 지정된 타임 아웃 간격이 경과할 때까지, 블록 상태가 된다. 값 INFINITE 는, 파일의 재생이 완료할 때까지, 애플리케이션이 무기한으로 블록 상태가 되는 것을 의미한다. 보다 현실적인 이벤트 처리의 예에 대해서는, 「이벤트에의 응답」을 참조할것.

애플리케이션이 종료하면 인터페이스의 포인터를 릴리즈 해, COM 라이브러리를 닫는다.

pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();

샘플 코드

이하는, 여기서 설명한 예의 코드 전체이다.

#include <dshow.h>
void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;

    // COM 라이브러리를 초기화한다.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

    // 필터 그래프 매니저를 생성 해, 인터페이스를 문의한다.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **) &pGraph);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Filter Graph Manager. ");
        return;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pEvent);

    // 그래프를 생성 한다.  중요 : 이 캐릭터 라인을 시스템 위에의 파일에 옮겨놓는다.
    hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
    if (SUCCEEDED(hr))
    {
        // 그래프를 실행한다.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // 완료할 때까지 대기한다.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // 주 : 실제의 애플리케이션에서는 INFINITE 를 사용하지 않는 것.
            // 무기한으로 블록 하는 경우가 있다.
        }
    }
    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();
}

참조

↑TOP