다음을 통해 공유


4단계. 할당자 속성 설정

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

변환 필터 작성 자습서의 4단계입니다.

참고

CTransInPlaceFilter에서 파생되는 필터에는 이 단계가 필요하지 않습니다.

 

두 핀이 미디어 유형에 동의하면 연결에 대한 할당자를 선택하고 버퍼 크기 및 버퍼 수와 같은 할당자 속성을 협상합니다.

CTransformFilter 클래스에는 두 개의 할당자가 있습니다. 하나는 업스트림 핀 연결용이고 다른 하나는 다운스트림 핀 연결용입니다. 업스트림 필터는 업스트림 할당자를 선택하고 할당자 속성도 선택합니다. 입력 핀은 업스트림 필터가 결정하는 모든 것을 허용합니다. 이 동작을 수정해야 하는 경우 CBaseInputPin::NotifyAllocator 메서드를 재정의합니다.

변환 필터의 출력 핀은 다운스트림 할당자를 선택합니다. 다음 단계를 수행합니다.

  1. 다운스트림 필터가 할당자를 제공할 수 있는 경우 출력 핀은 이 필터를 사용합니다. 그렇지 않으면 출력 핀이 새 할당자를 만듭니다.
  2. 출력 핀은 IMemInputPin::GetAllocatorRequirements를 호출하여 다운스트림 필터의 할당자 요구 사항(있는 경우)을 가져옵니다.
  3. 출력 핀은 순수 가상인 변환 필터의 CTransformFilter::D ecideBufferSize 메서드를 호출합니다. 이 메서드에 대한 매개 변수는 할당자에 대한 포인터이며 다운스트림 필터의 요구 사항이 있는 ALLOCATOR_PROPERTIES 구조체입니다. 다운스트림 필터에 할당자 요구 사항이 없으면 구조가 0이 됩니다.
  4. DecideBufferSize 메서드에서 파생 클래스는 IMemAllocator::SetProperties를 호출하여 할당자 속성을 설정합니다.

일반적으로 파생 클래스는 출력 형식, 다운스트림 필터의 요구 사항 및 필터 자체 요구 사항에 따라 할당자 속성을 선택합니다. 다운스트림 필터의 요청과 호환되는 속성을 선택해 보세요. 그렇지 않으면 다운스트림 필터가 연결을 거부할 수 있습니다.

다음 예제에서 RLE 인코더는 버퍼 크기, 버퍼 맞춤 및 버퍼 수에 대한 최소 값을 설정합니다. 접두사에 대해 다운스트림 필터가 요청한 값을 사용합니다. 접두사는 일반적으로 0바이트이지만 일부 필터에는 필요합니다. 예를 들어 AVI Mux 필터는 접두사를 사용하여 RIFF 헤더를 작성합니다.

HRESULT CRleFilter::DecideBufferSize(
    IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
    AM_MEDIA_TYPE mt;
    HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
    if (FAILED(hr))
    {
        return hr;
    }

    ASSERT(mt.formattype == FORMAT_VideoInfo);
    BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
    pProp->cbBuffer = DIBSIZE(*pbmi) * 2; 
    if (pProp->cbAlign == 0)
    {
        pProp->cbAlign = 1;
    }
    if (pProp->cBuffers == 0)
    {
        pProp->cBuffers = 1;
    }
    // Release the format block.
    FreeMediaType(mt);

    // Set allocator properties.
    ALLOCATOR_PROPERTIES Actual;
    hr = pAlloc->SetProperties(pProp, &Actual);
    if (FAILED(hr)) 
    {
        return hr;
    }
    // Even when it succeeds, check the actual result.
    if (pProp->cbBuffer > Actual.cbBuffer) 
    {
        return E_FAIL;
    }
    return S_OK;
}

할당자가 요청과 정확히 일치하지 않을 수 있습니다. 따라서 SetProperties 메서드는 실제 결과를 별도의 ALLOCATOR_PROPERTIES 구조체(이전 예제의 Actual 매개 변수)로 반환합니다. SetProperties가 성공하더라도 결과를 검사 필터의 최소 요구 사항을 충족하는지 확인해야 합니다.

사용자 지정 할당자

기본적으로 모든 필터 클래스는 할당자에 CMemAllocator 클래스를 사용합니다. 이 클래스는 클라이언트 프로세스의 가상 주소 공간에서 메모리를 할당합니다( VirtualAlloc 사용). 필터가 DirectDraw 표면과 같은 다른 종류의 메모리를 사용해야 하는 경우 사용자 지정 할당자를 구현할 수 있습니다. CBaseAllocator 클래스를 사용하거나 완전히 새로운 할당자 클래스를 작성할 수 있습니다. 필터에 사용자 지정 할당자가 있는 경우 할당자를 사용하는 핀에 따라 다음 메서드를 재정의합니다.

다른 필터가 사용자 지정 할당자를 사용하여 연결을 거부하는 경우 필터가 연결에 실패하거나 다른 필터의 할당자와 연결할 수 있습니다. 후자의 경우 할당자 유형을 나타내는 내부 플래그를 설정해야 할 수 있습니다. 이 방법의 예제는 CDrawImage 클래스를 참조하세요.

다음: 5단계. 이미지를 변환합니다.

DirectShow 필터 작성