DirectShow의 Data Flow 개요

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

이 섹션에서는 DirectShow에서 데이터 흐름이 작동하는 방식에 대한 광범위한 개요를 제공합니다. 자세한 내용은 설명서의 다른 섹션에서 찾을 수 있습니다.

데이터는 단순히 바이트 배열인 버퍼에 보관됩니다. 각 버퍼는 IMediaSample 인터페이스를 구현하는 미디어 샘플이라는 COM 개체에 의해 래핑됩니다. 샘플은 IMemAllocator 인터페이스를 구현하는 할당자라고 하는 다른 유형의 개체에 의해 생성됩니다. 두 개 이상의 핀 연결이 동일한 할당자를 공유할 수 있지만 모든 핀 연결에 할당자가 할당됩니다. 다음 이미지는 이 프로세스를 보여 줍니다.

버퍼, 샘플 및 할당자

각 할당자는 미디어 샘플 풀을 만들고 각 샘플에 대한 버퍼를 할당합니다. 필터가 데이터로 버퍼를 채워야 할 때마다 IMemAllocator::GetBuffer를 호출하여 할당자에서 샘플을 요청합니다. 할당자에 다른 필터에서 현재 사용하지 않는 샘플이 있는 경우 GetBuffer 메서드는 샘플에 대한 포인터를 사용하여 즉시 반환됩니다. 할당자의 모든 샘플이 사용 중인 경우 메서드는 샘플을 사용할 수 있게 될 때까지 차단합니다. 메서드가 샘플을 반환하는 경우 필터는 데이터를 버퍼에 넣고 샘플에 적절한 플래그(일반적으로 타임스탬프를 포함)를 설정하고 샘플 다운스트림을 제공합니다.

렌더러 필터가 샘플을 받으면 타임스탬프를 확인하고 필터 그래프의 참조 클록이 데이터를 렌더링해야 한다는 것을 나타낼 때까지 샘플을 유지합니다. 필터가 데이터를 렌더링한 후 샘플을 해제합니다. 샘플의 참조 수가 0이 될 때까지 샘플은 할당자의 샘플 풀로 돌아가지 않습니다. 즉, 모든 필터가 샘플을 릴리스했습니다. 다음 이미지는 이 프로세스를 보여 줍니다.

무료 미디어 샘플을 기다리는 디코더

업스트림 필터는 렌더러보다 앞서 실행될 수 있습니다. 즉, 렌더러가 버퍼를 사용하는 것보다 더 빠르게 채울 수 있습니다. 그럼에도 불구하고 렌더러는 프레젠테이션 시간까지 각각을 보유하기 때문에 샘플은 일찍 렌더링되지 않습니다. 또한 GetSample은 그렇지 않은 샘플만 반환하므로 업스트림 필터는 버퍼를 실수로 덮어쓰지 않습니다. 업스트림 필터를 미리 실행할 수 있는 양은 할당자 풀의 샘플 수에 따라 결정됩니다.

이전 다이어그램은 할당자 하나만 표시하지만 일반적으로 스트림당 여러 할당자가 있습니다. 따라서 렌더러가 샘플을 해제하면 연속 효과가 있을 수 있습니다. 다음 다이어그램에서는 디코더가 렌더러가 샘플을 해제할 때까지 기다리는 동안 압축된 비디오 프레임을 보유하는 상황을 보여 줍니다. 파서 필터도 디코더가 샘플을 해제하기를 기다리고 있습니다.

샘플을 기다리는 두 개의 필터

렌더러가 샘플을 해제하면 디코더의 GetBuffer 에 대한 보류 중인 호출이 반환됩니다. 그런 다음 디코더는 압축된 비디오 프레임을 디코딩하고 보유하고 있던 샘플을 해제하여 파서의 보류 중인 GetBuffer 호출을 차단 해제할 수 있습니다.

필터 그래프의 Data Flow