DirectShow DirectShow 튜토리얼 AVI 파일의 재압축 재압축 그래프의 생성 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
다음에 나타내는 것은, AVI 파일재압축용의 일반적인 필터 그래프이다.
AVI 스플리터 필터는,파일 소스 (비동기) 필터로부터 데이터를 꺼내, 그 데이터를 비디오 스트림과 오디오 스트림에 해석한다. 비데오디컴프레서는 압축 비디오를 디코드해, 디코드된 비압축 비디오는 비디오 압력에 의해 재압축된다. 디컴프레서의 선택은 소스 파일에 의해 정해진다. 이 선택은,인텔리전트 접속에 의해 자동적으로 처리된다. 애플리케이션은, 보통은 사용자에 대해서 일람을 제시해 압력을 선택해야 한다 ( 「압축 필터의 선택」을 참조할것).
압축 비디오는, 다음에 AVI Mux 필터 에게 건네진다. 이 예의 오디오 스트림은 압축되지 않기 때문에, AVI 스플리터로부터 직접 AVI Mux 에게 건네진다. AVI Mux 는 2 개의 스트림을 인터리브 해,파일 라이터 필터가 출력을 디스크에 기입한다. 원의 파일에 오디오 스트림이 없는 경우에서도, AVI Mux 가 필요한 점에 주의 해야 한다.
이 필터 그래프를 생성 하는 가장 간단한 방법은,캡춰 그래프 빌더를 사용하는 것이다. 이것은, 캡춰 그래프 및 그 외의 커스텀 필터 그래프를 생성하기 위한 DirectShow 구성 요소이다.
최초로,CoCreateInstance 를 호출해, 캡춰 그래프 빌더를 생성 한다.
ICaptureGraphBuilder2 *pBuild = NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **) &pBuild);
다음에, 그 캡춰 그래프 빌더를 사용해, 필터 그래프를 생성 한다.
이러한 각 순서에 대해 이하로 설명한다.
렌더링 섹션을 생성 한다
그래프의 렌더링 섹션을 생성 하려면 ,ICaptureGraphBuilder2::SetOutputFileName 메서드를 호출한다. 이 메서드는, 출력의 미디어 서브 타입과 출력 파일의 이름을 지정하는 입력 파라미터를 받는다. MUX 필터와 파일 라이터의 포인터를 돌려준다. MUX 필터는, 그래프 생성의 다음의 단계에서 필요하게 된다. 파일 라이터의 포인터는 이 예에서는 필요없기 때문에, NULL 로 하는 것이 가능하다.
IBaseFilter *pMux = NULL;
hr = pBuild->SetOutputFileName(
&MEDIASUBTYPE_Avi, // 파일 타입.
wszOutputFile, // 와이드 문자의 캐릭터 라인으로서의 파일명.
&pMux, // 멀티플렉서의 포인터를 얻어온다.
NULL); // 파일 라이터의 포인터를 얻어온다.
이 메서드가 돌아가면 MUX 필터에는 미처리의 참조 카운트가 남아 있으므로, 다음에 반드시 포인터를 릴리즈 할 필요가 있다.
다음 그림은 현상의 필터 그래프를 나타낸다.
MUX 필터는, AVI 포맷을 제어하기 위해서 이하의 2 개의 인터페이스를 공개하고 있다.
소스 필터와 압축 필터를 추가한다
다음의 순서에서는, 소스 필터와 압축 필터를 필터 그래프에 추가한다. SetOutputFileName 를 호출하면, 캡춰 그래프 빌더가 자동적으로 필터 그래프 매니저의 인스턴스를 생성 한다. ICaptureGraphBuilder2::GetFiltergraph 메서드를 호출해, 그 인스턴스의 포인터를 얻어온다.
IGraphBuilder *pGraph = NULL;
hr = pBuild->GetFiltergraph(&pGraph);
다음에,IGraphBuilder::AddSourceFilter 메서드를 호출해 비동기 파일 소스 필터를 추가해,IFilterGraph::AddFilter 메서드를 호출해 비디오 압력을 추가한다.
IBaseFilter *pSrc = NULL;
hr = pGraph->AddSourceFilter(wszInputFile, L"Source Filter", &pSrc);
hr = pGraph->AddFilter(pVComp, L"Compressor");
다음 그림이 나타내듯 아직 소스 필터와 압축 필터는, 그래프내의 다른 것과는 접속되지 않다.
소스를 Mux 에 접속한다
마지막 순서에서는, 비디오 압력을 개입시켜 소스 필터를 AVI Mux 필터에 접속한다. ICaptureGraphBuilder2::RenderStream 메서드를 사용해, 소스 필터의 출력 핀이 지정된 싱크 필터에 접속한다. 옵션으로 압축 필터를 통한다.
최초의 2 개의 파라미터로, 핀 카테고리와 미디어 타입을 지정해, 소스 필터의 핀중 접속하는 핀을 지정한다. 비동기 파일 소스 필터에는 출력 핀은 1 개 밖에 없기 때문에, 이러한 파라미터는 NULL 로 할 필요가 있다. 다음의 3 개의 파라미터로, 소스 필터, 압축 필터 (있는 경우), Mux 필터를 지정한다.
이하의 샘플 코드에서는, 비디오 압력을 개입시켜 비디오 스트림을 렌더링 한다.
hr = pBuild->RenderStream(
NULL, // 출력 핀 카테고리.
NULL, // 미디어 타입.
pSrc, // 소스 필터.
pVComp, // 압축 필터.
pMux); // 싱크 필터 (AVI Mux).
다음 그림은 현상의 필터 그래프를 나타낸다.
소스 파일에 오디오 스트림이 있으면 가정해,AVI 스플리터 필터는 오디오용의 출력 핀을 생성 했다. 이 핀을 접속하려면 , 다시 RenderStream 를 호출한다.
hr = pBuild->RenderStream(NULL, NULL, pSrc, NULL, pMux);
여기에서는, 압축 필터는 지정하고 있지 않다. 소스 필터의 출력 핀은 이미 접속되고 있으므로,RenderStream 메서드는 스플리터 필터의 미접속의 출력 핀을 찾는다. 다음에, 오디오 핀을 찾아내 그 핀을 MUX 필터에 직접 접속한다. 소스 파일에 오디오 스트림이 없는 경우, 2 번째의 RenderStream 의 호출은 예상 대로 실패한다. 그러나,RenderStream 에의 최초의 호출로 그래프는 완성하므로, 2 번째의 호출이 실패해도 문제는 없다.
이 예에서는, 2 개의 RenderStream 호출의 순서가 중요하다. 2 번째의 호출에서는 압력은 지정하지 않기 때문에, AVI 스플리터로부터의 임의의 미접속 핀을 접속한다. 이 호출을 이제 1 개의 호출보다 먼저 실행 하면, 이 메서드는 비디오 압력을 개좌도에 비디오 스트림을 AVI Mux 에 접속할 가능성이 있다. 따라서, 보다 한정된 (압축 필터를 사용한) 호출을 먼저 실행할 필요가 있다.
전의 설명에서는, 소스 필터가 AVI 파일이라고 가정하고 있었다. 그러나, 이 방법은 MPEG 파일등의 다른 파일 타입에도 적용할 수 있다. 결과의 필터 그래프는, 약간 다른 것이 된다.