다음을 통해 공유


압축 다시 압축 그래프 빌드

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

AVI 파일 압축 해제에 대한 일반적인 필터 그래프는 다음과 같습니다.

avi 압축 해제 그래프

AVI 분할기 필터파일 원본(비동기) 필터에서 데이터를 가져와서 비디오 및 오디오 스트림으로 구문 분석합니다. 비디오 압축 해제기는 압축된 비디오를 디코딩하여 비디오 압축기에서 압축을 다시압축합니다. 압축 해제기의 선택은 원본 파일에 따라 달라집니다. 지능형 연결에서 자동으로 처리됩니다. 애플리케이션은 일반적으로 사용자에게 목록을 표시하여 압축기를 선택해야 합니다. ( 압축 필터 선택을 참조하세요.)

그러면 압축된 비디오가 AVI Mux 필터로 이동합니다. 이 예제의 오디오 스트림은 압축되지 않으므로 AVI 분할자에서 AVI Mux로 직접 이동합니다. AVI Mux는 두 스트림을 인터리브하고 파일 기록기 필터 는 출력을 디스크에 씁니다. 원본 파일에 오디오 스트림이 없더라도 AVI Mux가 필요합니다.

이 필터 그래프를 빌드하는 가장 쉬운 방법은 캡처 그래프 및 기타 사용자 지정 필터 그래프를 빌드하기 위한 DirectShow 구성 요소인 캡처 그래프 작성기를 사용하는 것입니다.

먼저 CoCreateInstance를 호출하여 캡처 그래프 작성기를 만듭니다.

ICaptureGraphBuilder2 *pBuild = NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, 
                        NULL, CLSCTX_INPROC_SERVER,
    IID_ICaptureGraphBuilder2, (void **)&pBuild);

그런 다음, 캡처 그래프 작성기를 사용하여 필터 그래프를 빌드합니다.

  1. AVI Mux 필터 및 파일 작성기를 포함하는 그래프의 렌더링 섹션을 빌드합니다.
  2. 원본 필터와 압축 필터를 그래프에 추가합니다.
  3. 원본 필터를 MUX 필터에 연결합니다. 캡처 그래프 작성기에서는 원본 파일을 구문 분석하는 데 필요한 분할기 및 디코더 필터를 삽입합니다. 또한 압축 필터를 통해 비디오 및 오디오 스트림을 라우팅할 수 있습니다.

다음 섹션에서는 이러한 각 단계를 설명합니다.

렌더링 섹션 빌드

그래프의 렌더링 섹션을 빌드하려면 ICaptureGraphBuilder2::SetOutputFileName 메서드를 호출합니다. 이 메서드는 출력의 미디어 하위 형식과 출력 파일의 이름을 지정하는 입력 매개 변수를 사용합니다. MUX 필터 및 파일 기록기에 대한 포인터를 반환합니다. MUX 필터는 그래프 빌드의 다음 단계에 필요합니다. 이 예제에서는 파일 작성기에 대한 포인터가 필요하지 않으므로 매개 변수가 NULL일 수 있습니다.

IBaseFilter *pMux = NULL;
hr = pBuild->SetOutputFileName(
        &MEDIASUBTYPE_Avi, // File type. 
        wszOutputFile,     // File name, as a wide-character string.
        &pMux,             // Receives a pointer to the multiplexer.
        NULL);             // Receives a pointer to the file writer. 

메서드가 반환되면 MUX 필터에 미해결 참조 수가 있으므로 나중에 포인터를 놓아야 합니다.

다음 다이어그램은 이 시점에서 필터 그래프를 보여 있습니다.

필터 그래프의 렌더링 섹션

MUX 필터는 AVI 형식을 제어하기 위한 두 가지 인터페이스를 노출합니다.

원본 및 압축 필터 추가

다음 단계는 필터 그래프에 원본 및 압축 필터를 추가하는 것입니다. SetOutputFileName을 호출할 때 캡처 그래프 작성기가 필터 그래프 관리자의 instance 자동으로 만듭니다. 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 메서드를 사용합니다.

처음 두 매개 변수는 핀 범주와 미디어 유형을 지정하여 연결할 원본 필터의 핀을 지정합니다. 비동기 파일 원본 필터에는 출력 핀이 하나만 있으므로 이러한 매개 변수는 NULL이어야 합니다. 다음 세 매개 변수는 원본 필터, 압축 필터(있는 경우) 및 Mux 필터를 지정합니다.

다음 코드 예제에서는 비디오 압축기를 통해 비디오 스트림을 렌더링합니다.

hr = pBuild->RenderStream(
        NULL,       // Output pin category
        NULL,       // Media type
        pSrc,       // Source filter
        pVComp,     // Compression filter
        pMux);      // Sink filter (the AVI Mux)

다음 다이어그램은 지금까지의 필터 그래프를 보여줍니다.

렌더링된 비디오 스트림

원본 파일에 오디오 스트림이 있다고 가정하면 AVI 분할기 필터에서 오디오에 대한 출력 핀을 만들었습니다. 이 핀을 연결하려면 RenderStream을 다시 호출합니다.

hr = pBuild->RenderStream(NULL, NULL, pSrc, NULL, pMux);

여기서는 압축 필터가 지정되지 않습니다. 소스 필터의 출력 핀이 이미 연결되어 있으므로 RenderStream 메서드는 분할기 필터에서 연결되지 않은 출력 핀을 검색합니다. 오디오 핀을 찾아 MUX 필터에 직접 연결합니다. 원본 파일에 오디오 스트림이 없으면 RenderStream에 대한 두 번째 호출이 실패합니다. 이는 정상적인 동작입니다. RenderStream에 대한 첫 번째 호출 후에 그래프가 완료되므로 두 번째 호출의 실패는 무해합니다.

이 예제에서는 두 RenderStream 호출의 순서가 중요합니다. 두 번째 호출은 압축기를 지정하지 않으므로 AVI 분할기에서 연결되지 않은 핀을 연결합니다. 이 호출을 다른 호출 앞에 두면 비디오 압축기 없이 비디오 스트림을 AVI Mux에 연결할 수 있습니다. 따라서 압축 필터를 사용하여 보다 구체적인 호출이 먼저 발생해야 합니다.

이전 설명에서는 원본 파일이 AVI 파일이라고 가정했습니다. 그러나 이 기술은 MPEG 파일과 같은 다른 파일 형식에서도 작동합니다. 결과 필터 그래프는 다소 다릅니다.

AVI 파일 압축 다시 압축