다음을 통해 공유


DMO에서 미디어 형식 설정

[DirectShow 이 페이지와 연결된 기능은 레거시 기능입니다. MediaPlayer, IMFMediaEngine, Media Foundation 오디오/비디오 캡처대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11에 최적화되었습니다. Microsoft는 가능하면 새로운 코드에서 MediaPlayer, IMFMediaEngineAudio/Video Capture를 DirectShow대신 Media Foundation 사용하는 것이 좋습니다. 가능한 경우 레거시 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를 직접 호스팅하는