Utiliser des interfaces de filtre DirectShow personnalisées¶
Video Capture SDK .Net Video Edit SDK .Net Media Player SDK .Net
Remarque : l'API présentée dans ce guide est la même pour tous nos produits SDK, y compris Video Capture SDK .Net, Video Edit SDK .Net et Media Player SDK .Net.
DirectShow est un framework multimédia puissant qui permet aux développeurs d'effectuer des opérations complexes sur les flux multimédias. L'une de ses forces clés est la capacité à travailler avec des interfaces de filtre personnalisées, vous donnant un contrôle précis sur le traitement des médias. Ce guide vous accompagne dans l'implémentation et l'utilisation d'interfaces de filtre DirectShow personnalisées dans vos applications .NET.
Comprendre les filtres DirectShow¶
DirectShow utilise une architecture basée sur les filtres où chaque filtre effectue une opération spécifique sur le flux multimédia. Ces filtres sont connectés dans un graphe, créant un pipeline pour le traitement des médias.
Composants clés de DirectShow¶
- Filtre : un composant qui traite les données multimédias
- Pin : points de connexion entre les filtres
- Graphe de filtres : le pipeline complet de filtres connectés
- IBaseFilter : l'interface fondamentale que tous les filtres DirectShow implémentent
Prise en main des interfaces de filtre personnalisées¶
Pour travailler avec les filtres DirectShow en .NET, vous devrez :
- Ajouter les références appropriées à votre projet
- Accéder au filtre via les événements appropriés
- Convertir le filtre vers l'interface dont vous avez besoin
- Implémenter votre logique personnalisée
Références de projet requises¶
Pour accéder à la fonctionnalité DirectShow, incluez le paquet approprié dans votre projet :
<PackageReference Include="VisioForge.DotNet.Core" Version="X.X.X" />
Vous pouvez aussi ajouter la référence à l'assembly VisioForge.Core directement dans votre projet.
Implémenter l'accès à une interface de filtre personnalisé¶
Notre SDK fournit plusieurs événements qui vous donnent accès aux filtres au fur et à mesure qu'ils sont ajoutés au graphe de filtres. Voici comment les utiliser efficacement :
Accéder aux filtres dans Video Capture SDK¶
Le Video Capture SDK propose l'événement OnFilterAdded qui est déclenché chaque fois qu'un filtre est ajouté au graphe. Cet événement fournit l'accès à chaque filtre via ses arguments d'événement.
// S'abonner à l'événement OnFilterAdded
videoCaptureCore.OnFilterAdded += VideoCaptureCore_OnFilterAdded;
// Implémentation du gestionnaire d'événements
private void VideoCaptureCore_OnFilterAdded(object sender, FilterEventArgs eventArgs)
{
// Accéder à l'interface du filtre DirectShow
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
// Vous pouvez maintenant travailler avec le filtre via l'interface IBaseFilter
if (baseFilter != null)
{
// Le code de manipulation du filtre personnalisé va ici
}
}
Travailler avec l'interface IBaseFilter¶
L'interface IBaseFilter est la base des filtres DirectShow. Voici ce que vous pouvez en faire :
Récupérer les informations du filtre¶
private void GetFilterInfo(IBaseFilter filter)
{
FilterInfo filterInfo = new FilterInfo();
int hr = filter.QueryFilterInfo(out filterInfo);
if (hr >= 0)
{
Console.WriteLine($"Filter Name: {filterInfo.achName}");
// N'oubliez pas de libérer la référence au graphe de filtres
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
Énumérer les pins du filtre¶
private void EnumerateFilterPins(IBaseFilter filter)
{
IEnumPins enumPins;
int hr = filter.EnumPins(out enumPins);
if (hr >= 0 && enumPins != null)
{
IPin[] pins = new IPin[1];
int fetched;
while (enumPins.Next(1, pins, out fetched) == 0 && fetched > 0)
{
PinInfo pinInfo = new PinInfo();
pins[0].QueryPinInfo(out pinInfo);
Console.WriteLine($"Pin Name: {pinInfo.name}, Direction: {pinInfo.dir}");
// Libérer le pin et l'info
if (pinInfo.filter != null)
Marshal.ReleaseComObject(pinInfo.filter);
Marshal.ReleaseComObject(pins[0]);
}
Marshal.ReleaseComObject(enumPins);
}
}
Identifier le bon filtre¶
Lorsque vous travaillez avec l'événement OnFilterAdded, gardez à l'esprit qu'il peut être appelé plusieurs fois au fur et à mesure que divers filtres sont ajoutés au graphe. Pour travailler avec un filtre spécifique, vous devrez l'identifier correctement :
private void VideoCaptureCore_OnFilterAdded(object sender, FilterEventArgs eventArgs)
{
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
if (baseFilter != null)
{
FilterInfo filterInfo = new FilterInfo();
baseFilter.QueryFilterInfo(out filterInfo);
// Vérifier si c'est le filtre que nous cherchons
if (filterInfo.achName == "Video Capture Device")
{
// C'est notre filtre cible, effectuer les opérations spécifiques
ConfigureVideoCaptureFilter(baseFilter);
}
// Libérer la référence au graphe de filtres
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
Configuration avancée du filtre¶
Une fois que vous avez accès à l'interface du filtre, vous pouvez effectuer des configurations avancées :
Définir les propriétés du filtre¶
private void SetFilterProperty(IBaseFilter filter, Guid propertySet, int propertyId, object propertyValue)
{
IKsPropertySet propertySetInterface = filter as IKsPropertySet;
if (propertySetInterface != null)
{
// Convertir la valeur de propriété en tableau d'octets
byte[] propertyData = ConvertToByteArray(propertyValue);
// Définir la propriété
int hr = propertySetInterface.Set(
propertySet,
propertyId,
IntPtr.Zero,
0,
propertyData,
propertyData.Length
);
Marshal.ReleaseComObject(propertySetInterface);
}
}
Récupérer les propriétés du filtre¶
private object GetFilterProperty(IBaseFilter filter, Guid propertySet, int propertyId, Type propertyType)
{
IKsPropertySet propertySetInterface = filter as IKsPropertySet;
object result = null;
if (propertySetInterface != null)
{
int dataSize = Marshal.SizeOf(propertyType);
byte[] propertyData = new byte[dataSize];
int returnedDataSize;
// Obtenir la propriété
int hr = propertySetInterface.Get(
propertySet,
propertyId,
IntPtr.Zero,
0,
propertyData,
propertyData.Length,
out returnedDataSize
);
if (hr >= 0)
{
result = ConvertFromByteArray(propertyData, propertyType);
}
Marshal.ReleaseComObject(propertySetInterface);
}
return result;
}
Cas d'usage courants des interfaces de filtre personnalisées¶
Filtres de traitement vidéo¶
Lorsque vous travaillez avec la vidéo, vous pourriez avoir besoin d'accéder à des propriétés spécifiques des périphériques caméra :
private void ConfigureVideoCaptureFilter(IBaseFilter captureFilter)
{
// Accéder aux propriétés de la caméra et les définir
IAMCameraControl cameraControl = captureFilter as IAMCameraControl;
if (cameraControl != null)
{
// Définir l'exposition
cameraControl.Set(CameraControlProperty.Exposure, 0, CameraControlFlags.Manual);
// Définir la mise au point
cameraControl.Set(CameraControlProperty.Focus, 0, CameraControlFlags.Manual);
Marshal.ReleaseComObject(cameraControl);
}
}
Filtres de traitement audio¶
Pour le traitement audio, vous voudrez peut-être ajuster le volume ou les paramètres de qualité audio :
private void ConfigureAudioFilter(IBaseFilter audioFilter)
{
// Accéder à l'interface de volume
IBasicAudio basicAudio = audioFilter as IBasicAudio;
if (basicAudio != null)
{
// Définir le volume (0 à -10000, où 0 est le max et -10000 le min)
basicAudio.put_Volume(-2000); // 80% du volume
Marshal.ReleaseComObject(basicAudio);
}
}
Gérer correctement les ressources¶
Lorsque vous travaillez avec des interfaces DirectShow, il est crucial de libérer correctement les objets COM pour éviter les fuites de mémoire :
private void ReleaseComObject(object comObject)
{
if (comObject != null)
{
Marshal.ReleaseComObject(comObject);
}
}
Exemple complet¶
Voici un exemple plus complet qui montre comment trouver et configurer un filtre de capture vidéo :
using System;
using System.Runtime.InteropServices;
using VisioForge.Libs.DirectShowLib; // Namespace public — IBaseFilter, FilterInfo, IPin, etc.
public class CustomFilterExample
{
private VideoCaptureCore captureCore;
public void Initialize()
{
captureCore = new VideoCaptureCore();
captureCore.OnFilterAdded += CaptureCore_OnFilterAdded;
// Configurer la source
// ...
// Démarrer la capture
captureCore.Start();
}
private void CaptureCore_OnFilterAdded(object sender, FilterEventArgs eventArgs)
{
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
if (baseFilter != null)
{
// Obtenir les informations du filtre
FilterInfo filterInfo = new FilterInfo();
baseFilter.QueryFilterInfo(out filterInfo);
Console.WriteLine($"Filter added: {filterInfo.achName}");
// Vérifier si c'est le filtre de capture vidéo
if (filterInfo.achName.Contains("Video Capture"))
{
ConfigureVideoCaptureFilter(baseFilter);
}
// Libérer la référence au graphe de filtres
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
private void ConfigureVideoCaptureFilter(IBaseFilter captureFilter)
{
// Votre code de configuration de filtre ici
}
public void Cleanup()
{
if (captureCore != null)
{
captureCore.Stop();
captureCore.OnFilterAdded -= CaptureCore_OnFilterAdded;
captureCore.Dispose();
captureCore = null;
}
}
}
Composants système requis¶
Pour utiliser la fonctionnalité DirectShow dans votre application, assurez-vous que vos utilisateurs finaux disposent des composants suivants :
- DirectX Runtime (inclus avec Windows)
- Composants redistribuables du SDK
Conclusion¶
Travailler avec des interfaces de filtre DirectShow personnalisées vous donne des capacités puissantes pour le traitement multimédia dans vos applications .NET. En suivant les modèles décrits dans ce guide, vous pouvez accéder aux composants DirectShow sous-jacents et les manipuler pour obtenir un contrôle précis sur vos applications multimédias.
Pour une aide supplémentaire sur l'implémentation de ces techniques, veuillez contacter notre équipe de support. Visitez notre dépôt GitHub pour plus d'exemples de code et d'exemples d'implémentation.