Deinterlace 기본 설정 설정

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

VMR(비디오 혼합 렌더러)은 하드웨어 가속 디인터레이싱을 지원하여 인터레이스된 비디오의 렌더링 품질을 향상시킵니다. 사용 가능한 정확한 기능은 기본 하드웨어에 따라 달라집니다. 애플리케이션은 하드웨어 디인터레이싱 기능을 쿼리하고 IVMRDeinterlaceControl 인터페이스(VMR-7 ) 또는 IVMRDeinterlaceControl9 인터페이스(VMR-9)를 통해 디인터레이싱 기본 설정을 지정할 수 있습니다. 디인터레이싱은 스트림별로 수행됩니다.

VMR-7과 VMR-9 간의 인터레이스 동작에는 한 가지 중요한 차이점이 있습니다. 그래픽 하드웨어가 고급 디인터레이싱을 지원하지 않는 시스템에서 VMR-7은 하드웨어 오버레이로 대체되어 BOB 스타일 디인터레이를 사용하도록 지시할 수 있습니다. 이 경우 VMR이 30fps를 보고하지만 비디오는 실제로 초당 60회 대칭 이동으로 렌더링됩니다.

하드웨어 오버레이를 사용하는 VMR-7의 경우를 제외하고 VMR의 믹서에서 디인터레이싱을 수행합니다. 믹서는 DXVA(DirectX Video Acceleration) 디인터레이싱 DDI(디바이스 드라이버 인터페이스)를 사용하여 디인터레이싱을 수행합니다. 이 DDI는 애플리케이션에서 호출할 수 없으며 애플리케이션은 VMR의 디인터레이싱 기능을 대체할 수 없습니다. 그러나 애플리케이션은 이 섹션에 설명된 대로 원하는 디인터레이싱 모드를 선택할 수 있습니다.

참고

이 섹션에서는 IVMRDeinterlaceControl9 메서드에 대해 설명하지만 VMR-7 버전은 거의 동일합니다.

 

비디오 스트림에 대한 디인터레이싱 기능을 얻으려면 다음을 수행합니다.

  1. 비디오 스트림에 대한 설명과 함께 VMR9VideoDesc 구조를 채웁니다. 이 구조를 채우는 방법에 대한 자세한 내용은 나중에 제공됩니다.
  2. 구조를 IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes 메서드에 전달합니다. 메서드를 두 번 호출합니다. 첫 번째 호출은 하드웨어가 지정된 형식에 대해 지원하는 deinterlace 모드의 수를 반환합니다. 이 크기의 GUID 배열을 할당하고 메서드를 다시 호출하여 배열의 주소를 전달합니다. 두 번째 호출은 배열을 GUID로 채웁니다. 각 GUID는 하나의 디인터레이싱 모드를 식별합니다.
  3. 특정 모드의 capabiltiies를 얻으려면 IVMRDeinterlaceControl9::GetDeinterlaceModeCaps 메서드를 호출합니다. 배열의 GUID 중 하나와 함께 동일한 VMR9VideoDesc 구조를 전달합니다. 메서드는 VMR9DeinterlaceCaps 구조를 모드 기능으로 채웁니다.

다음은 이러한 단계를 보여 주는 코드입니다.

VMR9VideoDesc VideoDesc; 
DWORD dwNumModes = 0;
// Fill in the VideoDesc structure (not shown).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc, 
    &dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
    // Allocate an array for the GUIDs that identify the modes.
    GUID *pModes = new GUID[dwNumModes];
    if (pModes)
    {
        // Fill the array.
        hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc, 
            &dwNumModes, pModes);
        if (SUCCEEDED(hr))
        {
            // Loop through each item and get the capabilities.
            for (int i = 0; i < dwNumModes; i++)
            {
                VMR9DeinterlaceCaps Caps;
                hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i, 
                    &VideoDesc, &Caps);
                if (SUCCEEDED(hr))
                {
                    // Examine the Caps structure.
                }
            }
        }
        delete [] pModes;
    }
}

이제 애플리케이션은 다음 메서드를 사용하여 스트림에 대한 디인터레이싱 모드를 설정할 수 있습니다.

  • SetDeinterlaceMode 메서드는 기본 모드를 설정합니다. GUID_NULL 사용하여 디인터레이싱을 해제합니다.
  • SetDeinterlacePrefs 메서드는 요청된 모드를 사용할 수 없는 경우 동작을 지정합니다.
  • GetDeinterlaceMode 메서드는 설정한 기본 모드를 반환합니다.
  • GetActualDeinterlaceMode 메서드는 사용 중인 실제 모드를 반환하며, 기본 모드를 사용할 수 없는 경우 대체 모드일 수 있습니다.

메서드 참조 페이지에서 자세한 정보를 제공합니다.

VMR9VideoDesc 구조체 사용

이전에 제공된 절차에서 첫 번째 단계는 비디오 스트림에 대한 설명과 함께 VMR9VideoDesc 구조를 채우는 것입니다. 먼저 비디오 스트림의 미디어 형식을 가져옵니다. VMR 필터의 입력 핀에서 IPin::ConnectionMediaType 을 호출하여 이 작업을 수행할 수 있습니다. 그런 다음 비디오 스트림이 인터레이스되는지 확인합니다. VIDEOINFOHEADER2 형식만 인터레이스할 수 있습니다. 형식 형식이 FORMAT_VideoInfo 경우 프로그레시브 프레임이어야 합니다. 형식 형식이 FORMAT_VideoInfo2 경우 AMINTERLACE_IsInterlaced 플래그에 대해 dwInterlaceFlags 필드를 검사. 이 플래그가 있으면 비디오가 인터레이스됨을 나타냅니다.

변수 pBMI가 형식 블록의 BITMAPINFOHEADER 구조체에 대한 포인터라고 가정합니다. VMR9VideoDesc 구조체에서 다음 값을 설정합니다.

  • dwSize: 이 필드를 로 sizeof(VMR9VideoDesc)설정합니다.

  • dwSampleWidth: 이 필드를 로 pBMI->biWidth설정합니다.

  • dwSampleHeight: 이 필드를 로 abs(pBMI->biHeight)설정합니다.

  • SampleFormat: 이 필드는 미디어 형식의 인터레이스 특성을 설명합니다. VIDEOINFOHEADER2 구조체에서 dwInterlaceFlags 필드를 확인하고 SampleFormat을 해당하는 VMR9_SampleFormat 플래그와 동일하게 설정합니다. 이 작업을 수행하는 도우미 함수는 아래에 제공됩니다.

  • InputSampleFreq: 이 필드는 VIDEOINFOHEADER2 구조체의 AvgTimePerFrame 필드에서 계산할 수 있는 입력 빈도를 제공합니다. 일반적으로 dwNumerator 를 10000000으로 설정하고 dwDenominatorAvgTimePerFrame으로 설정합니다. 그러나 잘 알려진 프레임 속도에 대해 검사 수도 있습니다.

    프레임당 평균 시간 프레임 속도(fps) 분자 분모
    166833 59.94(NTSC) 60000 1001
    333667 29.97(NTSC) 30000 1001
    417188 23.97(NTSC) 24000 1001
    200000 50.00(PAL) 50 1
    400000 25.00(PAL) 25 1
    416667 24.00 (영화) 24 1

     

  • OutputFrameFreq: 이 필드는 InputSampleFreq 값 및 입력 스트림의 인터리빙 특성에서 계산할 수 있는 출력 빈도를 제공합니다.

    • OutputFrameFreq.dwDenominatorInputSampleFreq.dwDenominator와 동일하게 설정합니다.
    • 입력 비디오가 인터리브되는 경우 OutputFrameFreq.dwNumerator 를 2 x InputSampleFreq.dwNumerator로 설정합니다. (디인터레이싱 후 프레임 속도는 두 배가 됩니다.) 그렇지 않으면 값을 InputSampleFreq.dwNumerator로 설정합니다.
  • dwFourCC: 이 필드를 로 pBMI->biCompression설정합니다.

다음 도우미 함수는 AMINTERLACE_X 플래그를 VMR9_SampleFormat 값으로 변환합니다.

#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)

VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
    if (IsInterlaced(dwInterlaceFlags)) {
        if (IsSingleField(dwInterlaceFlags)) {
            if (IsField1First(dwInterlaceFlags)) {
                return VMR9_SampleFieldSingleEven;
            }
            else {
                return VMR9_SampleFieldSingleOdd;
            }
        }
        else {
            if (IsField1First(dwInterlaceFlags)) {
                return VMR9_SampleFieldInterleavedEvenFirst;
             }
            else {
                return VMR9_SampleFieldInterleavedOddFirst;
            }
        }
    }
    else {
        return VMR9_SampleProgressiveFrame;  // Not interlaced.
    }
}