DirectShow DirectShow 의 사용법 Video Mixing Renderer 의 사용법 비인터레이스의 설정   [목차열람] [주소복사] [슬롯비우기]
비인터레이스의 설정
 
Microsoft DirectX 9.0

비인터레이스의 설정

Video Mixing Renderer (VMR)는 하드웨어에 의해 액셀러레이트 되는 비인터레이스를 지원 한다. 이 기능은, 인터레이스 된 비디오의 렌더링 품질을 개선한다. 실제로 이용할 수 있는 기능의 자세한 것은, 기본으로 되는 하드웨어에 따라서 다르다. 애플리케이션은 IVMRDeinterlaceControl 인터페이스 (VMR-7) 또는 IVMRDeinterlaceControl9 인터페이스 (VMR-9)를 개입시켜, 하드웨어의 비인터레이스 기능을 문의해 비인터레이스를 설정할 수 있다. 비인터레이스는 스트림 단위로 실행된다.

 :  여기에서는 IVMRDeinterlaceControl9 의 메서드에 대해 설명하지만, VMR-7 의 경우도 거의 같다.

비디오 스트림의 비인터레이스 기능을 얻어오려면, 다음의 작업을 실시한다.

  1. VMR9VideoDesc 구조체에 비디오 스트림의 설명을 저장 한다. 이 구조체에 데이터를 저장 하는 방법에 대해서는, 다음에 설명한다.
  2. IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes 메서드에 이 구조체를 건네준다. 메서드를 2 회 호출한다. 최초의 호출에서는, 하드웨어가 지정된 포맷에 지원 하고 있는 비인터레이스 모드의 수를 돌려준다. 이 사이즈의 GUID 의 배열을 할당해 배열의 주소를 건네주어 한번 더 메서드를 호출한다. 2 번째의 호출에 의해, 배열에 GUID 를 넣는다. 각 GUID 는 1 개의 비인터레이스 모드를 식별한다.
  3. 특정의 모드의 기능을 얻어오려면,IVMRDeinterlaceControl9::GetDeinterlaceModeCaps 메서드를 호출한다. 같은 VMR9VideoDesc 구조체 및 배열의 GUID 의 1 개를 건네준다. 이 메서드는 VMR9DeinterlaceCaps 구조체에 모드 기능을 저장 한다.

다음 코드에 이러한 순서를 나타낸다.

VMR9VideoDesc VideoDesc; 
DWORD dwNumModes = 0;
// VideoDesc 구조체에 데이터를 넣는다 (생략).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc, 
    &dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
    // 모드를 식별하는 GUID 의 배열을 할당한다.
    GUID *pModes = new GUID[dwNumModes];
    if (pModes)
    {
        // 배열에 데이터를 넣는다.
        hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc, 
            &dwNumModes, pModes);
        if (SUCCEEDED(hr))
        {
            // 각 아이템을 루프 해, 기능을 얻어온다.
            for (int i = 0; i < dwNumModes; i++)
            {
                VMR9DeinterlaceCaps Caps;
                hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i, 
                    &VideoDesc, &Caps);
                if (SUCCEEDED(hr))
                {
                    // Caps 구조체를 조사한다.
                }
            }
        }
        delete [] pModes;
    }
}

애플리케이션은, 다음의 메서드를 사용해 스트림의 비인터레이스 모드를 설정할 수 있게 되었다.

메서드의 레퍼런스 페이지에는, 한층 더 자세한 설명이 게재되고 있다.

VMR9VideoDesc 구조체의 사용법

전에 설명한 순서로, 최초로 VMR9VideoDesc 구조체에 비디오 스트림의 설명을 저장 했다. 처음에, 비디오 스트림의 미디어 타입을 얻어온다. 거기에는, VMR 필터의 입력 핀의 IPin::ConnectionMediaType 를 호출한다. 다음에, 비디오 스트림이 인터레이스 되고 있는지를 확인한다. VIDEOINFOHEADER2 포맷만 인터레이스 할 수 있다. 포맷 타입이 FORMAT_VideoInfo 인 경우는, 반드시 프로그래시브 프레임이다. 포맷 타입이 FORMAT_VideoInfo2 인 경우는,dwInterlaceFlags 필드에서 AMINTERLACE_IsInterlaced 플래그의 유무를 조사한다. 이 플래그가 있는 경우, 비디오는 인터레이스화 되고 있다.

변수 pBMI 가 포맷 블록의 BITMAPINFOHEADER 구조체의 포인터이라고 상정한다. VMR9VideoDesc 구조체에 다음의 값을 설정한다.

다음의 헬퍼-함수는 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;  // 인터레이스되지 않다.
    }
}
↑TOP