Uso de Interfaces de Filtros DirectShow Personalizados¶
Video Capture SDK .Net Video Edit SDK .Net Media Player SDK .Net
Nota: La API mostrada en esta guía es la misma en todos nuestros productos SDK, incluyendo Video Capture SDK .Net, Video Edit SDK .Net y Media Player SDK .Net.
DirectShow es un framework multimedia poderoso que permite a los desarrolladores realizar operaciones complejas en flujos de medios. Una de sus fortalezas clave es la capacidad de trabajar con interfaces de filtros personalizados, dándote control preciso sobre el procesamiento de medios. Esta guía te guiará a través de la implementación y utilización de interfaces de filtros DirectShow personalizados en tus aplicaciones .NET.
Entendiendo los Filtros DirectShow¶
DirectShow usa una arquitectura basada en filtros donde cada filtro realiza una operación específica en el flujo de medios. Estos filtros están conectados en un grafo, creando un pipeline para el procesamiento de medios.
Componentes Clave de DirectShow¶
- Filtro: Un componente que procesa datos de medios
- Pin: Puntos de conexión entre filtros
- Grafo de Filtros: El pipeline completo de filtros conectados
- IBaseFilter: La interfaz fundamental que todos los filtros DirectShow implementan
Comenzando con Interfaces de Filtros Personalizados¶
Para trabajar con filtros DirectShow en .NET, necesitarás:
- Agregar las referencias apropiadas a tu proyecto
- Acceder al filtro a través de eventos apropiados
- Convertir el filtro a la interfaz que necesitas
- Implementar tu lógica personalizada
Referencias de Proyecto Requeridas¶
Para acceder a la funcionalidad DirectShow, incluye el paquete apropiado en tu proyecto:
También puedes agregar la referencia al ensamblado VisioForge.Core directamente a tu proyecto.
Implementando Acceso a Interfaz de Filtro Personalizado¶
Nuestro SDK proporciona varios eventos que te dan acceso a los filtros a medida que se agregan al grafo de filtros. Aquí está cómo usarlos efectivamente:
Accediendo a Filtros en Video Capture SDK¶
El Video Capture SDK ofrece el evento OnFilterAdded que se dispara cada vez que un filtro se agrega al grafo. Este evento proporciona acceso a cada filtro a través de sus argumentos de evento.
// Suscribirse al evento OnFilterAdded
videoCaptureCore.OnFilterAdded += VideoCaptureCore_OnFilterAdded;
// Implementación del manejador de eventos
private void VideoCaptureCore_OnFilterAdded(object sender, FilterAddedEventArgs eventArgs)
{
// Acceder a la interfaz del filtro DirectShow
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
// Ahora puedes trabajar con el filtro a través de la interfaz IBaseFilter
if (baseFilter != null)
{
// El código de manipulación de filtro personalizado va aquí
}
}
Trabajando con la Interfaz IBaseFilter¶
La interfaz IBaseFilter es la base de los filtros DirectShow. Esto es lo que puedes hacer con ella:
Recuperando Información del Filtro¶
private void ObtenerInfoFiltro(IBaseFilter filter)
{
FilterInfo filterInfo = new FilterInfo();
int hr = filter.QueryFilterInfo(out filterInfo);
if (hr >= 0)
{
Console.WriteLine($"Nombre del Filtro: {filterInfo.achName}");
// No olvides liberar la referencia al grafo de filtros
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
Enumerando Pines del Filtro¶
private void EnumerarPinesFiltro(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($"Nombre del Pin: {pinInfo.name}, Dirección: {pinInfo.dir}");
// Liberar pin e info
if (pinInfo.filter != null)
Marshal.ReleaseComObject(pinInfo.filter);
Marshal.ReleaseComObject(pins[0]);
}
Marshal.ReleaseComObject(enumPins);
}
}
Identificando el Filtro Correcto¶
Al trabajar con el evento OnFilterAdded, recuerda que puede ser llamado múltiples veces a medida que varios filtros se agregan al grafo. Para trabajar con un filtro específico, necesitarás identificarlo correctamente:
private void VideoCaptureCore_OnFilterAdded(object sender, FilterAddedEventArgs eventArgs)
{
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
if (baseFilter != null)
{
FilterInfo filterInfo = new FilterInfo();
baseFilter.QueryFilterInfo(out filterInfo);
// Verificar si este es el filtro que estamos buscando
if (filterInfo.achName == "Video Capture Device")
{
// Este es nuestro filtro objetivo, realizar operaciones específicas
ConfigurarFiltroCaptura(baseFilter);
}
// Liberar la referencia al grafo de filtros
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
Configuración Avanzada de Filtros¶
Una vez que tienes acceso a la interfaz del filtro, puedes realizar configuraciones avanzadas:
Estableciendo Propiedades del Filtro¶
private void EstablecerPropiedadFiltro(IBaseFilter filter, Guid propertySet, int propertyId, object propertyValue)
{
IKsPropertySet propertySetInterface = filter as IKsPropertySet;
if (propertySetInterface != null)
{
// Convertir valor de propiedad a array de bytes
byte[] propertyData = ConvertirAArrayBytes(propertyValue);
// Establecer la propiedad
int hr = propertySetInterface.Set(
propertySet,
propertyId,
IntPtr.Zero,
0,
propertyData,
propertyData.Length
);
Marshal.ReleaseComObject(propertySetInterface);
}
}
Recuperando Propiedades del Filtro¶
private object ObtenerPropiedadFiltro(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;
// Obtener la propiedad
int hr = propertySetInterface.Get(
propertySet,
propertyId,
IntPtr.Zero,
0,
propertyData,
propertyData.Length,
out returnedDataSize
);
if (hr >= 0)
{
result = ConvertirDesdeArrayBytes(propertyData, propertyType);
}
Marshal.ReleaseComObject(propertySetInterface);
}
return result;
}
Casos de Uso Comunes para Interfaces de Filtros Personalizados¶
Filtros de Procesamiento de Video¶
Al trabajar con video, podrías necesitar acceder a propiedades específicas de dispositivos de cámara:
private void ConfigurarFiltroCaptura(IBaseFilter captureFilter)
{
// Acceder y establecer propiedades de cámara
IAMCameraControl cameraControl = captureFilter as IAMCameraControl;
if (cameraControl != null)
{
// Establecer exposición
cameraControl.Set(CameraControlProperty.Exposure, 0, CameraControlFlags.Manual);
// Establecer enfoque
cameraControl.Set(CameraControlProperty.Focus, 0, CameraControlFlags.Manual);
Marshal.ReleaseComObject(cameraControl);
}
}
Filtros de Procesamiento de Audio¶
Para procesamiento de audio, podrías querer ajustar configuraciones de volumen o calidad de audio:
private void ConfigurarFiltroAudio(IBaseFilter audioFilter)
{
// Acceder a interfaz de volumen
IBasicAudio basicAudio = audioFilter as IBasicAudio;
if (basicAudio != null)
{
// Establecer volumen (0 a -10000, donde 0 es máx y -10000 es mín)
basicAudio.put_Volume(-2000); // 80% volumen
Marshal.ReleaseComObject(basicAudio);
}
}
Manejando Recursos Correctamente¶
Al trabajar con interfaces DirectShow, es crucial liberar correctamente los objetos COM para prevenir fugas de memoria:
private void LiberarObjetoCom(object comObject)
{
if (comObject != null)
{
Marshal.ReleaseComObject(comObject);
}
}
Ejemplo Completo¶
Aquí hay un ejemplo más completo que demuestra encontrar y configurar un filtro de captura de video:
using System;
using System.Runtime.InteropServices;
using VisioForge.Core.DirectShow;
public class EjemploFiltroPersonalizado
{
private VideoCaptureCore captureCore;
public void Inicializar()
{
captureCore = new VideoCaptureCore();
captureCore.OnFilterAdded += CaptureCore_OnFilterAdded;
// Configurar fuente
// ...
// Iniciar captura
captureCore.Start();
}
private void CaptureCore_OnFilterAdded(object sender, FilterAddedEventArgs eventArgs)
{
IBaseFilter baseFilter = eventArgs.Filter as IBaseFilter;
if (baseFilter != null)
{
// Obtener información del filtro
FilterInfo filterInfo = new FilterInfo();
baseFilter.QueryFilterInfo(out filterInfo);
Console.WriteLine($"Filtro agregado: {filterInfo.achName}");
// Verificar si este es el filtro de captura de video
if (filterInfo.achName.Contains("Video Capture"))
{
ConfigurarFiltroCaptura(baseFilter);
}
// Liberar referencia al grafo de filtros
if (filterInfo.pGraph != null)
{
Marshal.ReleaseComObject(filterInfo.pGraph);
}
}
}
private void ConfigurarFiltroCaptura(IBaseFilter captureFilter)
{
// Tu código de configuración de filtro aquí
}
public void Limpiar()
{
if (captureCore != null)
{
captureCore.Stop();
captureCore.OnFilterAdded -= CaptureCore_OnFilterAdded;
captureCore.Dispose();
captureCore = null;
}
}
}
Componentes de Sistema Requeridos¶
Para usar la funcionalidad DirectShow en tu aplicación, asegúrate de que tus usuarios finales tengan los siguientes componentes instalados:
- DirectX Runtime (incluido con Windows)
- Componentes redistribuibles del SDK
Conclusión¶
Trabajar con interfaces de filtros DirectShow personalizados te da capacidades poderosas para el procesamiento de medios en tus aplicaciones .NET. Siguiendo los patrones descritos en esta guía, puedes acceder y manipular los componentes DirectShow subyacentes para lograr control preciso sobre tus aplicaciones multimedia.
Para asistencia adicional con la implementación de estas técnicas, por favor contacta a nuestro equipo de soporte. Visita nuestro repositorio de GitHub para más ejemplos de código y ejemplos de implementación.