Udostępnij przez


Ustawianie preferencji deinterlace

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]

Renderowanie mieszania wideo (VMR) obsługuje sprzętowo przyspieszone usuwanie przeplotu, co poprawia jakość renderowania dla wideo z przeplotem. Dokładne dostępne funkcje zależą od podstawowego sprzętu. Aplikacja może wysyłać zapytania dotyczące możliwości usuwania przeplotu sprzętowego i ustawiać preferencje usuwania przeplotu za pomocą interfejsu IVMRDeinterlaceControl (VMR-7) lub IVMRDeinterlaceControl9 (VMR-9). Deinterlacing jest wykonywany indywidualnie dla każdego strumienia.

Istnieje jedna ważna różnica w zachowaniu między maszynami wirtualnymi VMR-7 i VMR-9. W systemach, w których sprzęt graficzny nie obsługuje zaawansowanego deinterlacingu, VMR-7 może wrócić do nakładki sprzętowej i poinstruować ją, aby używała deinterlacingu w stylu BOB. W tym przypadku, chociaż VMR zgłasza 30 kl./s, wideo jest faktycznie renderowane przy 60 odświeżeniach na sekundę.

Z wyjątkiem VMR-7, który używa nakładki sprzętowej, deinterlacing jest wykonywany przez mikser VMR. Mikser używa funkcji DirectX Video Acceleration (DXVA) deinterlacing device driver interface (DDI) do wykonania deinterlacingu. Ta funkcja DDI nie jest wywoływana przez aplikacje, a aplikacje nie mogą zastąpić funkcji deinterlacingu VMR. Jednak aplikacja może wybrać żądany tryb deinterlacingu, zgodnie z opisem w tej sekcji.

Notatka

W tej sekcji opisano metody IVMRDeinterlaceControl9, ale wersje VMR-7 są prawie identyczne.

 

Aby uzyskać możliwości deinterlacingu dla strumienia wideo, wykonaj następujące czynności:

  1. Wypełnij strukturę VMR9VideoDesc opisującą strumień wideo. Szczegóły dotyczące sposobu wypełniania tej struktury są podane później.
  2. Przekaż strukturę do metody IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes. Wywołaj metodę dwa razy. Pierwsze wywołanie zwraca liczbę trybów deinterlace, które obsługuje sprzęt dla określonego formatu. Przydziel tablicę identyfikatorów GUID tego rozmiaru i ponownie wywołaj metodę, przekazując adres tablicy. Drugie wywołanie wypełnia tablicę identyfikatorami GUID. Każdy identyfikator GUID identyfikuje jeden tryb deinterlacingu.
  3. Aby uzyskać możliwości określonego trybu, wywołaj metodę IVMRDeinterlaceControl9::GetDeinterlaceModeCaps. Przekaż tę samą strukturę VMR9VideoDesc wraz z jednym z identyfikatorów GUID z tablicy. Metoda wypełnia strukturę VMR9DeinterlaceCaps możliwościami trybu.

Poniższy kod przedstawia następujące kroki:

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;
    }
}

Teraz aplikacja może ustawić tryb deinterlacingu dla strumienia przy użyciu następujących metod:

  • Metoda SetDeinterlaceMode ustawia preferowany tryb. Użyj GUID_NULL, aby wyłączyć usuwanie przeplotu.
  • Metoda SetDeinterlacePrefs określa zachowanie, jeśli żądany tryb jest niedostępny.
  • Metoda GetDeinterlaceMode zwraca ustawiony preferowany tryb.
  • Metoda GetActualDeinterlaceMode zwraca używany tryb rzeczywisty, który może być trybem rezerwowym, jeśli preferowany tryb jest niedostępny.

Strony referencyjne metody zawierają więcej informacji.

Korzystanie ze struktury VMR9VideoDesc

W podanej wcześniej procedurze pierwszym krokiem jest wypełnienie struktury VMR9VideoDesc z opisem strumienia wideo. Zacznij od uzyskania typu nośnika strumienia wideo. Można to zrobić, wywołując IPin::ConnectionMediaType na pinie wejściowym filtru VMR. Następnie potwierdź, czy strumień wideo jest przeplotowany. Tylko formaty VIDEOINFOHEADER2 mogą być przeplatane. Jeśli typ formatu jest FORMAT_VideoInfo, musi być ramką progresywną. Jeśli typ formatu jest FORMAT_VideoInfo2, sprawdź pole dwInterlaceFlags pod kątem flagi AMINTERLACE_IsInterlaced. Obecność tej flagi wskazuje, że wideo jest przeplatane.

Załóżmy, że zmienna pBMI jest wskaźnikiem do struktury BITMAPINFOHEADER w bloku formatu. Ustaw następujące wartości w strukturze VMR9VideoDesc:

  • dwSize: ustaw to pole na sizeof(VMR9VideoDesc).

  • dwSampleWidth: należy ustawić to pole na pBMI->biWidth.

  • dwSampleHeight: ustaw to pole na wartość abs(pBMI->biHeight).

  • SampleFormat: to pole opisuje właściwości przeplotu nośnika. Sprawdź pole dwInterlaceFlags w strukturze VIDEOINFOHEADER2 i ustaw SampleFormat równą równoważnej flagi VMR9_SampleFormat. Poniżej podano funkcję pomocniczą.

  • InputSampleFreq: to pole określa częstotliwość wejściową, którą można obliczyć z pola AvgTimePerFrame w strukturze VIDEOINFOHEADER2. W ogólnym przypadku ustaw dwNumerator na 100000000 i ustaw dwDenominator na avgTimePerFrame. Można jednak również sprawdzić, czy istnieją dobrze znane szybkości klatek na sekundę:

    Średni czas na ramkę Liczba klatek na sekundę Licznik Mianownik
    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 (Film) 24 1

     

  • OutputFrameFreq: to pole daje częstotliwość wyjściową, którą można obliczyć z wartości InputSampleFreq oraz właściwości przeplatania strumienia wejściowego:

    • Ustaw OutputFrameFreq.dwDenominator równe InputSampleFreq.dwDenominator.
    • Jeśli wejściowe wideo jest przeplatane, ustaw OutputFrameFreq.dwNumerator na 2 x InputSampleFreq.dwNumerator. (Po deinterlacingu szybkość klatek jest podwoina). W przeciwnym razie ustaw wartość na InputSampleFreq.dwNumerator.
  • dwFourCC: ustaw to pole na wartość pBMI->biCompression.

Następująca funkcja pomocnika konwertuje flagiX AMINTERLACE_ na wartości 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.
    }
}