Effets vidéo personnalisésCustom video effects

Cet article explique comment créer un composant Windows Runtime implémentant l’interface IBasicVideoEffect pour créer des effets personnalisés de flux vidéo.This article describes how to create a Windows Runtime component that implements the IBasicVideoEffect interface to create custom effects for video streams. Vous pouvez utiliser les effets personnalisés avec plusieurs API Windows Runtime différentes, notamment MediaCapture, qui fournit un accès à la caméra d’un appareil, et MediaComposition, qui vous permet de créer des compositions complexes à partir de clips multimédias.Custom effects can be used with several different Windows Runtime APIs including MediaCapture, which provides access to a device's camera, and MediaComposition, which allows you to create complex compositions out of media clips.

Ajouter un effet personnalisé à votre applicationAdd a custom effect to your app

Un effet vidéo personnalisé est défini dans une classe qui implémente l’interface IBasicVideoEffect.A custom video effect is defined in a class that implements the IBasicVideoEffect interface. Cette classe ne peut pas être incluse directement dans le projet de votre application.This class can't be included directly in your app's project. À la place, vous devez utiliser un composant Windows Runtime pour héberger votre classe d’effet vidéo.Instead, you must use a Windows Runtime component to host your video effect class.

Ajouter un composant Windows Runtime pour votre effet vidéoAdd a Windows Runtime component for your video effect

  1. Dans Microsoft Visual Studio, quand votre solution est ouverte, accédez au menu Fichier, sélectionnez Ajouter->Nouveau projet.In Microsoft Visual Studio, with your solution open, go to the File menu and select Add->New Project.
  2. Sélectionnez le type de projet Composant Windows Runtime (Windows universel).Select the Windows Runtime Component (Universal Windows) project type.
  3. Pour cet exemple, nommez le projet VideoEffectComponent.For this example, name the project VideoEffectComponent. Ce nom sera référencé dans le code ultérieurement.This name will be referenced in code later.
  4. Cliquez sur OK.Click OK.
  5. Le modèle de projet crée une classe appelée Class1.cs.The project template creates a class called Class1.cs. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur l’icône de Class1.cs et sélectionnez Renommer.In Solution Explorer, right-click the icon for Class1.cs and select Rename.
  6. Renommez le fichier ExampleVideoEffect.cs.Rename the file to ExampleVideoEffect.cs. Visual Studio affiche une invite vous demandant si vous voulez mettre à jour toutes les références sous le nouveau nom.Visual Studio will show a prompt asking if you want to update all references to the new name. Cliquez sur Oui.Click Yes.
  7. Ouvrez ExampleVideoEffect.cs et mettez à jour la définition de classe pour implémenter l’interface IBasicVideoEffect.Open ExampleVideoEffect.cs and update the class definition to implement the IBasicVideoEffect interface.
public sealed class ExampleVideoEffect : IBasicVideoEffect

Vous devez inclure les espaces de noms suivants dans votre fichier de classe effet afin d’accéder à tous les types utilisés dans les exemples de cet article.You need to include the following namespaces in your effect class file in order to access all of the types used in the examples in this article.

using Windows.Media.Effects;
using Windows.Media.MediaProperties;
using Windows.Foundation.Collections;
using Windows.Graphics.DirectX.Direct3D11;
using Windows.Graphics.Imaging;

Implémentez l’interface IBasicVideoEffect à l’aide du traitement logicielImplement the IBasicVideoEffect interface using software processing

Votre effet vidéo doit implémenter toutes les méthodes et propriétés de l’interface IBasicVideoEffect .Your video effect must implement all of the methods and properties of the IBasicVideoEffect interface. Cette section vous explique la procédure d’implémentation simple de cette interface à l’aide d’un traitement logiciel.This section walks you through a simple implementation of this interface that uses software processing.

Close, méthodeClose method

Le système appelle la méthode Fermer sur votre classe lorsque l’effet doit être arrêté.The system will call the Close method on your class when the effect should shut down. Vous devez utiliser cette méthode pour supprimer les ressources que vous avez créées.You should use this method to dispose of any resources you have created. L’argument de la méthode est un MediaEffectClosedReason qui vous permet de savoir si l’effet a été fermé normalement, si une erreur s’est produite ou si l’effet ne prend pas en charge le format d’encodage requis.The argument to the method is a MediaEffectClosedReason that lets you know whether the effect was closed normally, if an error occurred, or if the effect does not support the required encoding format.

public void Close(MediaEffectClosedReason reason)
{
    // Dispose of effect resources
}

Méthode DiscardQueuedFramesDiscardQueuedFrames method

La méthode DiscardQueuedFrames est appelée lorsque votre effet doit être réinitialisé.The DiscardQueuedFrames method is called when your effect should reset. Dans ce cas, le scénario courant est que l’effet stocke les trames précédemment traitées pour les utiliser dans le traitement de la trame active.A typical scenario for this is if your effect stores previously processed frames to use in processing the current frame. Quand cette méthode est appelée, vous devez supprimer l’ensemble des trames précédentes que vous avez enregistrées.When this method is called, you should dispose of the set of previous frames you saved. Cette méthode peut être utilisée pour réinitialiser un état associé aux trames précédentes, pas seulement les trames vidéo cumulées.This method can be used to reset any state related to previous frames, not only accumulated video frames.

private int frameCount;
public void DiscardQueuedFrames()
{
    frameCount = 0;
}

IsReadOnly, propriétéIsReadOnly property

La propriété IsReadOnly permet au système de savoir si votre effet écrit dans la sortie de l’effet.The IsReadOnly property lets the system know if your effect will write to the output of the effect. Si votre application ne modifie pas les trames vidéo (par exemple, un effet qui effectue seulement une analyse des trames vidéo), vous devez définir cette propriété sur true. Ainsi, le système copie efficacement à votre place l’entrée de trame dans la sortie de trame.If your app does not modify the video frames (for example, an effect that only performs analysis of the video frames), you should set this property to true, which will cause the system to efficiently copy the frame input to the frame output for you.

Conseil

Quand la propriété IsReadOnly est définie sur true, le système copie la trame d’entrée sur la trame de sortie avant l’appel de ProcessFrame.When the IsReadOnly property is set to true, the system copies the input frame to the output frame before ProcessFrame is called. Le fait de définir la propriété IsReadOnly sur true ne vous empêche pas d’écrire sur les trames de sortie de l’effet dans ProcessFrame.Setting the IsReadOnly property to true does not restrict you from writing to the effect's output frames in ProcessFrame.

public bool IsReadOnly { get { return false; } }

Méthode SetEncodingPropertiesSetEncodingProperties method

Le système appelle SetEncodingProperties à votre effet pour vous indiquer les propriétés d’encodage du flux vidéo sur lequel l’effet s’applique.The system calls SetEncodingProperties on your effect to let you know the encoding properties for the video stream upon which the effect is operating. Cette méthode fournit également une référence à l’appareil Direct3D utilisé pour le rendu matériel.This method also provides a reference to the Direct3D device used for hardware rendering. L’utilisation de cet appareil est expliquée dans l’exemple de traitement matériel plus loin dans cet article.The usage of this device is shown in the hardware processing example later in this article.

private VideoEncodingProperties encodingProperties;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    this.encodingProperties = encodingProperties;
}

Propriété SupportedEncodingPropertiesSupportedEncodingProperties property

Le système vérifie la propriété SupportedEncodingProperties pour déterminer quelles propriétés d’encodage sont prises en charge par votre effet.The system checks the SupportedEncodingProperties property to determine which encoding properties are supported by your effect. Notez que si le consommateur de votre effet ne peut pas encoder une vidéo en utilisant les propriétés que vous spécifiez, il appelle Close sur votre effet et supprime votre effet du pipeline vidéo.Note that if the consumer of your effect can't encode video using the properties you specify, it will call Close on your effect and will remove your effect from the video pipeline.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties
{            
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };

        // If the list is empty, the encoding type will be ARGB32.
        // return new List<VideoEncodingProperties>();
    }
}

Notes

Si vous renvoyez une liste vide d’objets VideoEncodingProperties à partir de SupportedEncodingProperties, le système utilise par défaut le codage ARGB32.If you return an empty list of VideoEncodingProperties objects from SupportedEncodingProperties, the system will default to ARGB32 encoding.

 

Propriété SupportedMemoryTypesSupportedMemoryTypes property

Le système vérifie que la propriété SupportedMemoryTypes pour déterminer si l’effet va accéder aux trames vidéo dans la mémoire du logiciel ou dans la mémoire du matériel (GPU).The system checks the SupportedMemoryTypes property to determine whether your effect will access video frames in software memory or in hardware (GPU) memory. Si vous retournez MediaMemoryTypes. CPU, les trames d’entrée et de sortie qui contiennent des données d’image dans les objets SoftwareBitmap sont passées.If you return MediaMemoryTypes.Cpu, your effect will be passed input and output frames that contain image data in SoftwareBitmap objects. Si vous renvoyez MediaMemoryTypes.Gpu, l’effet sera transmis aux trames en entrée et en sortie qui contiennent des données d’image dans les objets IDirect3DSurface.If you return MediaMemoryTypes.Gpu, your effect will be passed input and output frames that contain image data in IDirect3DSurface objects.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Cpu; } }

Notes

Si vous spécifiez MediaMemoryTypes.GpuAndCpu, le système utilise la mémoire du GPU ou du système, selon laquelle est la plus performante pour le pipeline.If you specify MediaMemoryTypes.GpuAndCpu, the system will use either GPU or system memory, whichever is more efficient for the pipeline. Quand vous utilisez cette valeur, vous devez vérifier la méthode ProcessFrame pour voir si le SoftwareBitmap ou le IDirect3DSurface transmis dans la méthode contient des données, puis traiter la trame en fonction.When using this value, you must check in the ProcessFrame method to see whether the SoftwareBitmap or IDirect3DSurface passed into the method contains data, and then process the frame accordingly.

 

Propriété TimeIndependentTimeIndependent property

La propriété TimeIndependent permet au système de savoir si votre effet n’exige pas un minutage uniforme.The TimeIndependent property lets the system know if your effect does not require uniform timing. Lorsqu’elle est définie sur true, le système peut utiliser les optimisations qui améliorent la performance de l’effet.When set to true, the system can use optimizations that enhance effect performance.

public bool TimeIndependent { get { return true; } }

Méthode SetPropertiesSetProperties method

La méthode SetProperties permet à l’application qui utilise votre effet d’ajuster les paramètres d’effet.The SetProperties method allows the app that is using your effect to adjust effect parameters. Les propriétés sont transmises sous la forme d’une carte de IPropertySet de noms et de valeurs de propriétés.Properties are passed as an IPropertySet map of property names and values.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}

Cet exemple simple estompe les pixels dans chaque trame vidéo en fonction d’une valeur spécifiée.This simple example will dim the pixels in each video frame according to a specified value. Une propriété est déclarée et TryGetValue est utilisé pour obtenir la valeur définie par l’application d’appel.A property is declared and TryGetValue is used to get the value set by the calling app. Si aucune valeur n’a été définie, la valeur par défaut .5 est utilisée.If no value was set, a default value of .5 is used.

public double FadeValue
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("FadeValue", out val))
        {
            return (double)val;
        }
        return .5;
    }
}

Méthode ProcessFrameProcessFrame method

C’est dans la méthode ProcessFrame que l’effet modifie les données d’image de la vidéo.The ProcessFrame method is where your effect modifies the image data of the video. La méthode est appelée une fois par trame et un objet ProcessVideoFrameContext lui est transmis.The method is called once per frame and is passed a ProcessVideoFrameContext object. Cet objet contient un objet VideoFrame en entrée qui contient la trame entrante à traiter et un objet VideoFrame en sortie sur lequel vous écrivez des données d’image qui seront transmises dans le reste du pipeline vidéo.This object contains an input VideoFrame object that contains the incoming frame to be processed and an output VideoFrame object to which you write image data that will be passed on to rest of the video pipeline. Chacun de ces objets VideoFrame comporte une propriété SoftwareBitmap et une propriété Direct3DSurface, mais lesquels d’entre eux peuvent être utilisés est déterminé par la valeur renvoyée à partir de la propriété SupportedMemoryTypes.Each of these VideoFrame objects has a SoftwareBitmap property and a Direct3DSurface property, but which of these can be used is determined by the value you returned from the SupportedMemoryTypes property.

Cet exemple montre une implémentation simple de la méthode ProcessFrame à l’aide du traitement logiciel.This example shows a simple implementation of the ProcessFrame method using software processing. Pour plus d’informations sur l’utilisation des objets SoftwareBitmap, voir Acquisition d’images.For more information about working with SoftwareBitmap objects, see Imaging. Un exemple d’implémentation de ProcessFrame à l’aide du traitement logiciel est illustré plus loin dans cet article.An example ProcessFrame implementation using hardware processing is shown later in this article.

L’accès à la mémoire tampon de données d’un SoftwareBitmap nécessite l’interopérabilité COM. Vous devez donc inclure l’espace de noms System.Runtime.InteropServices dans votre fichier de classe effet.Accessing the data buffer of a SoftwareBitmap requires COM interop, so you should include the System.Runtime.InteropServices namespace in your effect class file.

using System.Runtime.InteropServices;

Ajoutez le code suivant à l’intérieur de l’espace de noms de l’effet pour importer l’interface et accéder à la mémoire tampon d’image.Add the following code inside the namespace for your effect to import the interface for accessing the image buffer.

[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
    void GetBuffer(out byte* buffer, out uint capacity);
}

Notes

Dans la mesure où cette technique accède à une mémoire tampon d’image native non gérée, vous devez configurer votre projet pour autoriser du code unsafe.Because this technique accesses a native, unmanaged image buffer, you will need to configure your project to allow unsafe code.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet VideoEffectComponent et sélectionnez Propriétés.In Solution Explorer, right-click the VideoEffectComponent project and select Properties.
  2. Sélectionnez l’onglet Build .Select the Build tab.
  3. Activez la case à cocher autoriser le code unsafe .Select the Allow unsafe code check box.

 

Vous pouvez maintenant ajouter l’implémentation de la méthode ProcessFrame.Now you can add the ProcessFrame method implementation. Tout d’abord, cette méthode obtient un objet BitmapBuffer à partir des bitmaps logiciels en entrée et en sortie.First, this method obtains a BitmapBuffer object from both the input and output software bitmaps. Notez que la trame en sortie est ouverte pour l’écriture, et que la trame en entrée l’est pour la lecture.Note that the output frame is opened for writing and the input for reading. Ensuite, un IMemoryBufferReference est obtenu pour chaque tampon en appelant CreateReference.Next, an IMemoryBufferReference is obtained for each buffer by calling CreateReference. Ensuite, le tampon de données réel est obtenu en transtypant les objets IMemoryBufferReference en tant qu’interface d’interopérabilité COM définie ci-dessus, IMemoryByteAccess, puis en appelant GetBuffer.Then, the actual data buffer is obtained by casting the IMemoryBufferReference objects as the COM interop interface defined above, IMemoryByteAccess, and then calling GetBuffer.

Maintenant que les tampons de données ont été obtenus, vous pouvez lire à partir du tampon en entrée et écrire sur le tampon en sortie.Now that the data buffers have been obtained, you can read from the input buffer and write to the output buffer. La disposition de la mémoire tampon est obtenue en appelant GetPlaneDescription, qui fournit des informations sur la largeur, la Stride et le décalage initial de la mémoire tampon.The layout of the buffer is obtained by calling GetPlaneDescription, which provides information on the width, stride, and initial offset of the buffer. Les bits par pixel sont déterminés par les propriétés d’encodage définies précédemment à l’aide de la méthode SetEncodingProperties .The bits per pixel is determined by the encoding properties set previously with the SetEncodingProperties method. Les informations sur le format du tampon sont utilisées pour trouver l’index dans le tampon pour chaque pixel.The buffer format information is used to find the index into the buffer for each pixel. La valeur du pixel du tampon source est copiée dans le tampon cible. Les valeurs de couleur sont multipliées par la propriété FadeValue définie pour cet effet afin de les diminuer du montant spécifié.The pixel value from the source buffer is copied into the target buffer, with the color values being multiplied by the FadeValue property defined for this effect to dim them by the specified amount.

public unsafe void ProcessFrame(ProcessVideoFrameContext context)
{
    using (BitmapBuffer buffer = context.InputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Read))
    using (BitmapBuffer targetBuffer = context.OutputFrame.SoftwareBitmap.LockBuffer(BitmapBufferAccessMode.Write))
    {
        using (var reference = buffer.CreateReference())
        using (var targetReference = targetBuffer.CreateReference())
        {
            byte* dataInBytes;
            uint capacity;
            ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);

            byte* targetDataInBytes;
            uint targetCapacity;
            ((IMemoryBufferByteAccess)targetReference).GetBuffer(out targetDataInBytes, out targetCapacity);

            var fadeValue = FadeValue;

            // Fill-in the BGRA plane
            BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
            for (int i = 0; i < bufferLayout.Height; i++)
            {
                for (int j = 0; j < bufferLayout.Width; j++)
                {

                    byte value = (byte)((float)j / bufferLayout.Width * 255);

                    int bytesPerPixel = 4; 
                    if (encodingProperties.Subtype != "ARGB32")
                    {
                        // If you support other encodings, adjust index into the buffer accordingly
                    }
                    

                    int idx = bufferLayout.StartIndex + bufferLayout.Stride * i + bytesPerPixel * j;

                    targetDataInBytes[idx + 0] = (byte)(fadeValue * (float)dataInBytes[idx + 0]);
                    targetDataInBytes[idx + 1] = (byte)(fadeValue * (float)dataInBytes[idx + 1]);
                    targetDataInBytes[idx + 2] = (byte)(fadeValue * (float)dataInBytes[idx + 2]);
                    targetDataInBytes[idx + 3] = dataInBytes[idx + 3];
                }
            }
        }
    }
}

Implémenter l’interface IBasicVideoEffect à l’aide du traitement matérielImplement the IBasicVideoEffect interface using hardware processing

La création d’un effet vidéo personnalisé à l’aide du traitement matériel (GPU) est presque identique à l’utilisation du traitement logiciel tel que décrit ci-dessus.Creating a custom video effect by using hardware (GPU) processing is almost identical to using software processing as described above. Cette section vous explique les différences dans un effet qui utilise le traitement matériel.This section will show the few differences in an effect that uses hardware processing. Cet exemple utilise l’API Windows Runtime Win2D.This example uses the Win2D Windows Runtime API. Pour plus d’informations sur l’utilisation de Win2D, voir la documentation Win2D.For more information about using Win2D, see the Win2D documentation.

Utilisez les étapes suivantes pour ajouter le package NuGet Win2D au projet que vous avez créé comme décrit dans la section Ajouter un effet personnalisé à votre application au début de cet article.Use the following steps to add the Win2D NuGet package to the project you created as described in the Add a custom effect to your app section at the beginning of this article.

Pour ajouter le package NuGet Win2D à votre projet d’effetTo add the Win2D NuGet package to your effect project

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet VideoEffectComponent et sélectionnez Gérer les packages NuGet.In Solution Explorer, right-click the VideoEffectComponent project and select Manage NuGet Packages.
  2. En haut de la fenêtre, sélectionnez l’onglet Explorer.At the top of the window, select the Browse tab.
  3. Dans la zone de recherche, entrez Win2D.In the search box, enter Win2D.
  4. Sélectionnez Win2D.uwp, puis Installer dans le volet droit.Select Win2D.uwp, and then select Install in the right pane.
  5. La boîte de dialogue Examiner les modifications vous indique le package à installer.The Review Changes dialog shows you the package to be installed. Cliquez sur OK.Click OK.
  6. Acceptez la licence de package.Accept the package license.

Outre les espaces de noms inclus dans l’installation de base du projet, vous devez inclure les espaces de noms suivants fournis par Win2D.In addition to the namespaces included in the basic project setup, you will need to include the following namespaces provided by Win2D.

using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas;

Dans la mesure où cet effet utilisera la mémoire GPU pour les opérations sur les données d’image, vous devez renvoyer MediaMemoryTypes.Gpu à partir de la propriété SupportedMemoryTypes.Because this effect will use GPU memory for operating on the image data, you should return MediaMemoryTypes.Gpu from the SupportedMemoryTypes property.

public MediaMemoryTypes SupportedMemoryTypes { get { return MediaMemoryTypes.Gpu; } }

Définissez les propriétés de codage que votre effet prend en charge avec la propriété SupportedEncodingProperties.Set the encoding properties that your effect will support with the SupportedEncodingProperties property. Quand vous utilisez Win2D, vous devez utiliser le codage ARGB32.When working with Win2D, you must use ARGB32 encoding.

public IReadOnlyList<VideoEncodingProperties> SupportedEncodingProperties {
    get
    {
        var encodingProperties = new VideoEncodingProperties();
        encodingProperties.Subtype = "ARGB32";
        return new List<VideoEncodingProperties>() { encodingProperties };
    }
}

Utilisez la méthode SetEncodingProperties pour créer un nouvel objet CanvasDevice Win2D à partir du IDirect3DDevice transmis dans la méthode.Use the SetEncodingProperties method to create a new Win2D CanvasDevice object from the IDirect3DDevice passed into the method.

private CanvasDevice canvasDevice;
public void SetEncodingProperties(VideoEncodingProperties encodingProperties, IDirect3DDevice device)
{
    canvasDevice = CanvasDevice.CreateFromDirect3D11Device(device);
}

L’implémentation de SetProperties est identique à l’exemple de traitement logiciel précédent.The SetProperties implementation is identical to the previous software processing example. Cet exemple utilise une propriété BlurAmount pour configurer un effet de flou Win2D.This example uses a BlurAmount property to configure a Win2D blur effect.

private IPropertySet configuration;
public void SetProperties(IPropertySet configuration)
{
    this.configuration = configuration;
}
public double BlurAmount
{
    get
    {
        object val;
        if (configuration != null && configuration.TryGetValue("BlurAmount", out val))
        {
            return (double)val;
        }
        return 3;
    }
}

La dernière étape consiste à implémenter la méthode ProcessFrame qui traite réellement les données de l’image.The last step is to implement the ProcessFrame method that actually processes the image data.

À l’aide d’API Win2D, un CanvasBitmap est créé à partir de la propriété Direct3DSurface de la trame en entrée.Using Win2D APIs, a CanvasBitmap is created from the input frame's Direct3DSurface property. Un CanvasRenderTarget est créé à partir du Direct3DSurface de la trame en sortie et un CanvasDrawingSession est créé à partir de cette cible de rendu.A CanvasRenderTarget is created from the output frame's Direct3DSurface and a CanvasDrawingSession is created from this render target. Un nouveau GaussianBlurEffect Win2D est initialisé à l’aide de la propriété BlurAmount que l’effet expose via SetProperties.A new Win2D GaussianBlurEffect is initialized, using the BlurAmount property our effect exposes via SetProperties. Enfin, la méthode CanvasDrawingSession.DrawImage est appelée pour dessiner le bitmap en entrée sur la cible de rendu à l’aide de l’effet de flou.Finally, the CanvasDrawingSession.DrawImage method is called to draw the input bitmap to the render target using the blur effect.

public void ProcessFrame(ProcessVideoFrameContext context)
{

    using (CanvasBitmap inputBitmap = CanvasBitmap.CreateFromDirect3D11Surface(canvasDevice, context.InputFrame.Direct3DSurface))
    using (CanvasRenderTarget renderTarget = CanvasRenderTarget.CreateFromDirect3D11Surface(canvasDevice, context.OutputFrame.Direct3DSurface))
    using (CanvasDrawingSession ds = renderTarget.CreateDrawingSession())
    {


        var gaussianBlurEffect = new GaussianBlurEffect
        {
            Source = inputBitmap,
            BlurAmount = (float)BlurAmount,
            Optimization = EffectOptimization.Speed
        };

        ds.DrawImage(gaussianBlurEffect);

    }
}

Ajout d’un effet personnalisé à votre applicationAdding your custom effect to your app

Pour utiliser votre effet vidéo dans votre application, vous devez ajouter une référence au projet d’effet à votre application.To use your video effect from your app, you must add a reference to the effect project to your app.

  1. Dans l’Explorateur de solutions, sous votre projet d’application, cliquez avec le bouton droit sur Références, puis sélectionnez Ajouter une référence.In Solution Explorer, under your app project, right-click References and select Add reference.
  2. Développez l’onglet Projets, sélectionnez Solution, puis cochez la case du nom de votre projet d’effet.Expand the Projects tab, select Solution, and then select the check box for your effect project name. Dans cet exemple, le nom est VideoEffectComponent.For this example, the name is VideoEffectComponent.
  3. Cliquez sur OK.Click OK.

Ajouter un effet personnalisé à un flux vidéo de caméraAdd your custom effect to a camera video stream

Vous pouvez configurer un flux d’aperçu simple à partir de la caméra en suivant les étapes décrites dans l’article Accès à l’aperçu simple de l’appareil photo.You can set up a simple preview stream from the camera by following the steps in the article Simple camera preview access. Suivez ces étapes pour obtenir un objet MediaCapture initialisé qui est utilisé pour accéder au flux vidéo de l’appareil photo.Following those steps will provide you with an initialized MediaCapture object that is used to access the camera's video stream.

Pour ajouter votre effet vidéo personnalisé à un flux de caméra, créez d’abord un objet VideoEffectDefinition, en transmettant l’espace de noms et le nom de classe de votre effet.To add your custom video effect to a camera stream, first create a new VideoEffectDefinition object, passing in the namespace and class name for your effect. Appelez ensuite la méthode AddVideoEffect de l’objet MediaCapture pour ajouter l’effet au flux spécifié.Next, call the MediaCapture object's AddVideoEffect method to add your effect to the specified stream. Cet exemple utilise la valeur MediaStreamType.VideoPreview pour indiquer que l’effet doit être ajouté au flux d’aperçu.This example uses the MediaStreamType.VideoPreview value to specify that the effect should be added to the preview stream. Si votre application prend en charge la capture vidéo, vous pouvez également utiliser MediaStreamType.VideoRecord pour ajouter l’effet au flux de capture.If your app supports video capture, you could also use MediaStreamType.VideoRecord to add the effect to the capture stream. AddVideoEffect renvoie un objet IMediaExtension représentant votre effet personnalisé.AddVideoEffect returns an IMediaExtension object representing your custom effect. Vous pouvez utiliser la méthode SetProperties pour définir la configuration de votre effet.You can use the SetProperties method to set the configuration for your effect.

Une fois l’effet ajouté, StartPreviewAsync est appelé pour démarrer le flux d’aperçu.After the effect has been added, StartPreviewAsync is called to start the preview stream.

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect");

IMediaExtension videoEffect =
   await mediaCapture.AddVideoEffectAsync(videoEffectDefinition, MediaStreamType.VideoPreview);

videoEffect.SetProperties(new PropertySet() { { "FadeValue", .25 } });

await mediaCapture.StartPreviewAsync();

Ajouter un effet personnalisé à un clip dans une composition multimédiaAdd your custom effect to a clip in a MediaComposition

Pour obtenir des instructions générales sur la création des compositions multimédias à partir de clips vidéo, voir Compositions multimédias et modification.For general guidance for creating media compositions from video clips, see Media compositions and editing. L’extrait de code suivant illustre la création d’une composition multimédia simple qui utilise un effet vidéo personnalisé.The following code snippet shows the creation of a simple media composition that uses a custom video effect. Un objet MediaClip est créé en appelant CreateFromFileAsync, en transmettant un fichier vidéo sélectionné par l’utilisateur avec un FileOpenPicker et le clip est ajouté à un nouveau MediaComposition.A MediaClip object is created by calling CreateFromFileAsync, passing in a video file that was selected by the user with a FileOpenPicker, and the clip is added to a new MediaComposition. Ensuite, un objet VideoEffectDefinition est créé, en transmettant l’espace de noms et le nom de classe de votre effet au constructeur.Next a new VideoEffectDefinition object is created, passing in the namespace and class name for your effect to the constructor. Enfin, la définition de l’effet est ajoutée à la collection VideoEffectDefinitions de l’objet MediaClip.Finally, the effect definition is added to the VideoEffectDefinitions collection of the MediaClip object.

MediaComposition composition = new MediaComposition();
var clip = await MediaClip.CreateFromFileAsync(pickedFile);
composition.Clips.Add(clip);

var videoEffectDefinition = new VideoEffectDefinition("VideoEffectComponent.ExampleVideoEffect", new PropertySet() { { "FadeValue", .5 } });

clip.VideoEffectDefinitions.Add(videoEffectDefinition);