다음을 통해 공유


DMO에서 미디어 형식 설정

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

DMO가 데이터를 처리하기 전에 클라이언트는 각 스트림에 대한 미디어 형식을 설정해야 합니다. (이 규칙에는 한 가지 사소한 예외가 있습니다. 선택적 스트림을 참조하세요.) 스트림 수를 찾으려면 IMediaObject::GetStreamCount 메서드를 호출합니다.

DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);

이 메서드는 입력 수와 출력 수의 두 값을 반환합니다. 이러한 값은 DMO의 수명 동안 고정됩니다.

기본 설정 형식

모든 스트림에 대해 DMO는 기본 설정 순서대로 가능한 미디어 유형 목록을 할당합니다. 예를 들어 기본 설정 형식은 해당 순서대로 32-RGB, 24비트 RGB 및 16비트 RGB일 수 있습니다. 클라이언트가 미디어 형식을 설정하면 이러한 목록을 힌트로 사용할 수 있습니다. 스트림에 대한 기본 형식을 검색하려면 IMediaObject::GetInputType 메서드 또는 IMediaObject::GetOutputType 메서드를 호출합니다. 형식의 스트림 번호와 인덱스 값을 지정합니다(0부터 시작). 예를 들어 다음 코드는 첫 번째 입력 스트림에서 첫 번째 기본 설정 형식을 검색합니다.

DMO_MEDIA_TYPE mt
hr = pDMO->GetInputType(0, 0, &mt)
if (SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
}

지정된 스트림에서 기본 설정 미디어 형식을 모두 열거하려면 다음 예제와 같이 메서드가 DMO_E_NO_MORE_ITEMS 반환할 때까지 형식 인덱스를 증가시키는 루프를 사용합니다.

DMO_MEDIA_TYPE mt;
DWORD dwType = 0;
while (hr = pDMO->GetInputType(0, dwType, &mt), SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
    ++dwType;
}

기본 설정 형식에 대한 다음 사항에 유의해야 합니다.

  • DMO는 형식 블록이 없는 형식을 반환할 수 있습니다. 예를 들어 DMO는 이미지의 너비와 높이를 제공하지 않고 24비트 RGB와 같은 비디오 형식을 지정할 수 있습니다. 그러나 형식을 설정할 때는 전체 형식 블록을 제공해야 합니다. MIDI와 같은 일부 미디어 형식에는 서식 블록이 필요하지 않습니다. 이 경우 이 설명이 적용되지 않습니다.
  • DMO가 반환하는 기본 설정 형식의 모든 조합을 지원할 필요는 없습니다. 예를 들어 DMO에 두 개의 스트림이 있고 각 스트림에 네 가지 기본 설정 형식이 있는 경우 16개의 가능한 조합이 있지만 모두 유효하지는 않습니다.
  • 클라이언트가 한 스트림에 대한 미디어 형식을 설정하는 경우 DMO는 새 상태를 반영하도록 다른 스트림의 기본 형식을 업데이트할 수 있습니다. 그러나 그렇게 할 필요는 없습니다.
  • 일부 스트림의 경우 DMO는 기본 설정 형식을 제공하지 않을 수 있습니다. 일반적으로 DMO는 일부 스트림에서 적어도 몇 가지 기본 설정 형식을 제공해야 합니다.
  • DMO가 허용할 수 있는 미디어 유형의 전체 목록을 제공할 필요는 없습니다. DMO에서 지원하지만 기본 설정 형식으로 제공하지 않는 "수정되지 않은" 형식이 있을 수 있습니다.

즉, 클라이언트는 기본 설정 형식만 지침으로 처리해야 합니다. 지원되는 특정 형식을 알 수 있는 유일한 방법은 다음 섹션에 설명된 대로 테스트하는 것입니다.

스트림에서 미디어 형식 설정

IMediaObject::SetInputTypeIMediaObject::SetOutputType 메서드를 사용하여 각 스트림에 대한 형식을 설정합니다. 미디어 형식에 대한 전체 설명을 포함하는 DMO_MEDIA_TYPE 구조를 제공해야 합니다. 다음 예제에서는 44.1kHz 16비트 스테레오 PCM 오디오를 사용하여 입력 스트림 0에서 미디어 형식을 설정합니다.

DMO_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(DMO_MEDIA_TYPE));
// Allocate memory for the format block.
HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
if (SUCCEEDED(hr))
{
    // Set the type GUIDs.
    mt.majortype  = MEDIATYPE_Audio;
    mt.subtype    = MEDIASUBTYPE_PCM;
    mt.formattype = FORMAT_WaveFormatEx;

    // Initialize the format block.
    WAVEFORMATEX *pWave = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);
    pWave->wFormatTag = WAVE_FORMAT_PCM;
    pWave->nChannels = 2;
    pWave->nSamplesPerSec = 44100;
    pWave->wBitsPerSample = 16;
    pWave->nBlockAlign = (pWave->nChannels * pWave->wBitsPerSample) / 8;
    pWave->nAvgBytesPerSec = pWave->nSamplesPerSec * pWave->nBlockAlign;
    pWave->cbSize = 0;

    // Set the media type.
    hr = pDMO->SetInputType(0, &mt, 0); 

    // Release the format block.
    MoFreeMediaType(&mt);
}

미디어 형식을 설정하지 않고 테스트하려면 DMO_SET_TYPEF_TEST_ONLY 플래그를 사용하여 SetInputType 또는 SetOutputType 을 호출합니다. 메서드는 형식이 허용되는 경우 S_OK 반환하거나 그렇지 않으면 S_FALSE 반환합니다.

if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)
{
    // Media type is OK.
}

한 스트림의 설정이 다른 스트림에 영향을 줄 수 있으므로 스트림의 미디어 유형을 지워야 할 수 있습니다. 이렇게 하려면 DMO_SET_TYPEF_CLEAR 플래그를 사용하여 SetInputType 또는 SetOutputType 을 호출합니다.

디코더 DMO의 경우 클라이언트는 일반적으로 입력 형식을 먼저 설정한 다음 출력 형식을 선택합니다. 인코더 DMO의 경우 클라이언트는 먼저 출력 형식을 설정한 다음 입력 형식을 설정합니다.

DMO 직접 호스팅