다음을 통해 공유


DirectShow Editing Services에서 디코더 선택

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

[이 API는 지원되지 않으며 나중에 변경되거나 사용할 수 없습니다.]

DES(DirectShow Editing Services)가 비디오 편집 프로젝트를 렌더링하면 렌더링 엔진에서 필요한 디코더를 자동으로 선택합니다. 이 문제는 IRenderEngine::ConnectFrontEnd 메서드 내에서 발생하거나 렌더링 중에 동적으로 발생할 수 있습니다.

사용자는 특정 파일을 디코딩할 수 있는 여러 디코더를 설치할 수 있습니다. 여러 디코더를 사용할 수 있는 경우 DES는 Intelligent Connect 알고리즘을 사용하여 디코더를 선택합니다.

애플리케이션에서 사용할 디코더를 직접 지정할 수 있는 방법은 없습니다. 그러나 IAMGraphBuilderCallback 콜백 인터페이스를 통해 간접적으로 디코더를 선택할 수 있습니다. 애플리케이션에서 이 인터페이스를 구현하면 그래프 작성 프로세스 중에 알림을 받고 그래프에서 특정 필터를 거부할 수 있습니다.

먼저 IAMGraphBuilderCallback 인터페이스를 노출하는 클래스를 구현합니다.

class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
     // Method declarations (not shown).
};

그런 다음 Filter Graph Manager의 instance 만들고 클래스를 등록하여 콜백 알림을 받습니다.

// Declare an instance of the callback object.
GraphBuilderCB GraphCB; 

// Create the Filter Graph Manager.
CComPtr<IGraphBuilder> pGraph;
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
    // Handle error (not shown).
}
// Register to receive the callbacks.
CComQIPtr<IObjectWithSite> pSite(pGraph);
if (pSite)
{
    hr = pSite->SetSite((IUnknown*)&GraphCB);
}

그런 다음, 렌더링 엔진을 만들고 필터 그래프 관리자에 대한 포인터를 사용하여 IRenderEngine::SetFilterGraph 메서드를 호출합니다. 이렇게 하면 렌더링 엔진이 자체 필터 그래프 관리자를 만들지 않고 콜백에 대해 구성한 instance 대신 사용합니다.

CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
    // Handle error (not shown).
}

hr = pRender->SetFilterGraph(pGraph);

프로젝트가 렌더링되면 필터 Graph 관리자가 새 필터를 만들기 직전에 애플리케이션의 IAMGraphBuilderCallback::SelectedFilter 메서드가 호출됩니다. SelectedFilter 메서드는 필터의 모니커를 나타내는 IMoniker 인터페이스에 대한 포인터를 받습니다. 모니커를 검사하고 필터를 거부하려는 경우 SelectedFilter 메서드에서 오류 코드를 반환합니다.

어려운 부분은 디코더를 나타내는 모니커, 특히 거부하려는 디코더를 나타내는 모니커를 식별하는 것입니다. 한 가지 해결 방법은 다음과 같습니다.

  • 프로젝트를 렌더링하기 전에 IFilterMapper2::EnumMatchingFilters 메서드를 사용하여 원하는 입력 형식을 수락하는 것으로 등록된 필터 목록을 만듭니다. 비디오 또는 오디오 압축 유형의 경우 이 목록은 디코더 집합에 매핑되어야 합니다.

  • EnumMatchingFilters 메서드는 모니커 컬렉션을 반환합니다. 컬렉션의 각 모니커에 대해 필터 매퍼 사용에 설명된 대로 DisplayName 속성을 가져옵니다.

  • 표시 이름 목록을 저장하지만 디코딩에 사용할 필터와 일치하는 표시 이름을 생략합니다. 소프트웨어 필터의 표시 이름은 다음과 같습니다.

    OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");
    

    where

    CategoryGUID
    

    는 필터 범주의 GUID이고,

    FilterCLSID
    

    는 필터의 CLSID입니다. DDO의 경우 형식은 동일하지만 으로 변경 sw 합니다 dmo.

    이제 목록에 원하는 미디어 형식을 출력하지만 원하는 필터가 아닌 모든 필터에 대한 표시 이름이 포함됩니다.

  • SelectedFilter 메서드에서 제안된 모니커의 DisplayName 속성을 가져와서 저장된 목록에 검사. 표시 이름이 목록의 항목과 일치하는 경우 해당 필터를 거부합니다. 그렇지 않으면 S_OK 반환하여 수락합니다.

프로젝트 렌더링