Partager via


Définition des préférences de désinterlacer

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Le convertisseur de mixage vidéo (VMR) prend en charge le désinterlacement à accélération matérielle, ce qui améliore la qualité de rendu de la vidéo entrelacée. Les fonctionnalités exactes disponibles dépendent du matériel sous-jacent. L’application peut interroger les fonctionnalités de désinterlacation matérielle et définir des préférences de désinterlacation via l’interface IVMRDeinterlaceControl (VMR-7) ou l’interface IVMRDeinterlaceControl9 (VMR-9). Le désinterlacement est effectué par flux.

Il existe une différence importante dans le comportement d’entrelacement entre le VMR-7 et le VMR-9. Sur les systèmes où le matériel graphique ne prend pas en charge le désinterlacement avancé, le VMR-7 peut revenir à la superposition matérielle et lui demander d’utiliser une désinterlacation de style BOB. Dans ce cas, bien que le VMR signale 30 images/s, la vidéo est en fait rendue à 60 rotations par seconde.

Sauf dans le cas du VMR-7 utilisant la superposition matérielle, le désinterlacement est effectué par le mélangeur de VMR. Le mélangeur utilise l’interface du pilote de périphérique de désinterlacation DirectX Video Acceleration (DXVA) pour effectuer le désinterlacement. Cette DDI n’est pas appelable par les applications, et les applications ne peuvent pas remplacer la fonctionnalité de désinterlacation de VMR. Toutefois, une application peut sélectionner le mode de désinterlacation souhaité, comme décrit dans cette section.

Notes

Cette section décrit les méthodes IVMRDeinterlaceControl9 , mais les versions de VMR-7 sont presque identiques.

 

Pour obtenir les fonctionnalités de désinterlacation d’un flux vidéo, procédez comme suit :

  1. Renseignez une structure VMR9VideoDesc avec une description du flux vidéo. Vous trouverez plus tard des détails sur la façon de remplir cette structure.
  2. Passez la structure à la méthode IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes . Appelez la méthode deux fois. Le premier appel retourne le nombre de modes de désinterlacement pris en charge par le matériel pour le format spécifié. Allouez un tableau de GUID de cette taille, puis appelez à nouveau la méthode, en passant l’adresse du tableau. Le deuxième appel remplit le tableau avec des GUID. Chaque GUID identifie un mode de désinterlacation.
  3. Pour obtenir les capabiltiies d’un mode particulier, appelez la méthode IVMRDeinterlaceControl9::GetDeinterlaceModeCaps . Transmettez la même structure VMR9VideoDesc , ainsi que l’un des GUID du tableau. La méthode remplit une structure VMR9DeinterlaceCaps avec les fonctionnalités de mode.

Le code suivant illustre ces étapes :

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

À présent, l’application peut définir le mode de désinterlacation pour le flux à l’aide des méthodes suivantes :

  • La méthode SetDeinterlaceMode définit le mode préféré. Utilisez GUID_NULL pour désactiver le désinterlacement.
  • La méthode SetDeinterlacePrefs spécifie le comportement si le mode demandé n’est pas disponible.
  • La méthode GetDeinterlaceMode retourne le mode préféré que vous définissez.
  • La méthode GetActualDeinterlaceMode retourne le mode réel en cours d’utilisation, qui peut être un mode de secours, si le mode préféré n’est pas disponible.

Les pages de référence de méthode fournissent plus d’informations.

Utilisation de la structure VMR9VideoDesc

Dans la procédure donnée précédemment, la première étape consiste à remplir une structure VMR9VideoDesc avec une description du flux vidéo. Commencez par obtenir le type de média du flux vidéo. Pour ce faire, appelez IPin::ConnectionMediaType sur la broche d’entrée du filtre VMR. Vérifiez ensuite si le flux vidéo est entrelacé. Seuls les formats VIDEOINFOHEADER2 peuvent être entrelacés. Si le type de format est FORMAT_VideoInfo, il doit s’agir d’un frame progressif. Si le type de format est FORMAT_VideoInfo2, case activée le champ dwInterlaceFlags pour l’indicateur AMINTERLACE_IsInterlaced. La présence de cet indicateur indique que la vidéo est entrelacée.

Supposons que la variable pBMI soit un pointeur vers la structure BITMAPINFOHEADER dans le bloc de format. Définissez les valeurs suivantes dans la structure VMR9VideoDesc :

  • dwSize : définissez ce champ sur sizeof(VMR9VideoDesc).

  • dwSampleWidth : définissez ce champ sur pBMI->biWidth.

  • dwSampleHeight : définissez ce champ sur abs(pBMI->biHeight).

  • SampleFormat : ce champ décrit les caractéristiques entrelacs du type de média. Vérifiez le champ dwInterlaceFlags dans la structure VIDEOINFOHEADER2 et définissez SampleFormat sur l’indicateur de VMR9_SampleFormat équivalent. Une fonction d’assistance est indiquée ci-dessous.

  • InputSampleFreq : ce champ fournit la fréquence d’entrée, qui peut être calculée à partir du champ AvgTimePerFrame dans la structure VIDEOINFOHEADER2 . Dans le cas général, définissez dwNumerator sur 100000000 et dwDenominator sur AvgTimePerFrame. Toutefois, vous pouvez également case activée pour certaines fréquences d’images connues :

    Temps moyen par image Fréquence d’images (fps) Numérateur Dénominateur
    166833 59,94 (NTSC) 60000 1001
    333667 29,97 (NTSC) 30000 1001
    417188 23,97 (NTSC) 24 000 1001
    200000 50.00 (PAL) 50 1
    400000 25.00 (PAL) 25 1
    416667 24.00 (Film) 24 1

     

  • OutputFrameFreq : ce champ donne la fréquence de sortie, qui peut être calculée à partir de la valeur InputSampleFreq et des caractéristiques d’entrelacement du flux d’entrée :

    • Définissez OutputFrameFreq.dwDenominator sur InputSampleFreq.dwDenominator.
    • Si la vidéo d’entrée est entrelacée, définissez OutputFrameFreq.dwNumerator sur 2 x InputSampleFreq.dwNumerator. (Après le désinterlacement, la fréquence d’images est doublée.) Sinon, définissez la valeur sur InputSampleFreq.dwNumerator.
  • dwFourCC : définissez ce champ sur pBMI->biCompression.

La fonction d’assistance suivante convertit les indicateurs AMINTERLACE_X en valeurs 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.
    }
}