Cómo diseñar un filtro de transformación DIrectShow personalizado
Es muy difícil diseñar un filtro de transformación personalizado
Porque, en primer lugar, el filtro es un dll (extensión .ax), y escribir un proyecto dll requiere ciertos conocimientos de VC. Por lo tanto, se recomienda agregar primero algunos conocimientos sobre dll.
En segundo lugar, el registro de dll y la configuración del proyecto también son muy problemáticos. Por lo tanto, se recomienda que todos comprendan un poco dll
En segundo lugar, el registro de dll, la generación de GUID y la configuración del proyecto son muy problemáticos.
Además, faltan ejemplos listos para usar de filtros de conversión en Internet. El código fuente proporcionado por DirectShow (como NULLINPLACE y CONTRAST) es demasiado complejo, tiene cuadros de diálogo y páginas de propiedades. no es adecuado para principiantes y no tiene un Los ejemplos implican la conversión de formatos de imagen, mientras que el uso más común de filtros de conversión es el de medios. El mayor uso de los filtros es la conversión de tipos de medios, por lo que estos ejemplos no son aplicables
Como principiante, estos problemas me preocupaban profundamente. Después de estudiar mucho, finalmente salí del atolladero y de repente me iluminó. . Espero que pueda ser de ayuda para todos y también pueda considerarse como un resumen de 2008.
Mi ejemplo es diseñar un filtro de conversión para convertir medios YUY2 de 16 bits al tipo RGB24 de 24 bits.
La razón es que mi cámara web solo admite YUY2 de 16 bits y quiero obtener el mapa de bits. Quiero obtener un mapa de bits. Por cierto, quiero aprender a diseñar filtros
Los pasos específicos son los siguientes:
Configurar el entorno de desarrollo
1. En Tools-gt; Options-gt ; VC en Directorios establece la ruta al archivo de encabezado y la biblioteca del SDK de DirectX
2. Compile el código fuente de la clase base y genere strmbasd. Genere strmbasd.lib (versión de depuración), strmbase.lib (versión de lanzamiento)
3. El asistente de VC crea un nuevo proyecto win32 DLL (vacío)
4. Establezca -gt link; -gt; nombre del archivo de salida. YUV2RGBfilter.ax
5. Configure el enlace -gt; y agregue strmbasd.lib winmm.lib quartz.lib vfw32.lib (tenga en cuenta la ruta)
6. Defina un archivo .def con el mismo nombre y agréguelo al proyecto con el siguiente contenido:
LIBRARY YUV2RGBfilter.ax
Salida
DllMain PRIVATE
DllGetClassObject PRIVATE
p>DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
7. Cree la clase YUV2RGBfilter y cree su archivo cpp y h file
8. Defina la función de entrada y registro de la DLL en YUV2RGBfilter.cpp. Defina la función de entrada y registro de la DLL en YUV2RGBfilter.cpp.
cpp colóquelo al final del archivo cpp
//p>
// DllEntryPoint
//
extern "C " BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)( hModule), dwReason, lpReserved);
}
///////// / ///////////////////////////////////////////////// ///// ////////////
//
// Exportar punto de entrada para registro y baja
/ / (En este caso simplemente llaman a la implementación predeterminada).
//
/////////////////////////////////// // ////////////////////////////////////////
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
}
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
9. Archivos de encabezado que se incluirán en el archivo cpp
#include lt ; streams.hgt ;
#include lt;windows.hgt;
#include lt;initguid.// Nuestra propia guía pública
#include "YUV2RGBfilter .h"
Segundo filtro de desarrollo
1. Genere un GUID (ejecute la herramienta Guiden en modo de línea de comando) y cree un archivo separado llamado Y2Ruids.h para él. Referencia
#include lt;initguid.hgt;
// Objeto de filtro YUV2toRGB24
// {F91FC8FD-B1A6-49b0-A308-D6EDEAF405DA} p>
DEFINE_ GUID(CLSID_YUV2toRGB24,
0xf91fc8fd, 0xb1a6, 0x49b0, 0xa3, 0x8, 0xd6, 0xed, 0xea, 0xf4, 0x5, 0xda). /p>
2. Cree la clase CYUV2RGBfilter que hereda de CTransformFilter escrito en TransformFilter.
h
// ---------------------------------------- ------------------------------------
//Definición de clase de CYUV2RGBfilter
// ------------------------------------------ --- ----------------------------------
//
//
clase CYUV2RGBfilter: public CTransformFilter
{
public:
static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr );
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
DECLARE_IUNKNOWN
// anular la función virtual pura
HRESULT CheckInputType(const CMediaType *mtIn);
HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut
HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp); );
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);
privado: p>
//Constructor
CYUV2RGBfilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);
//Función miembro
VOID ChangeFormat( AM_MEDIA_TYPE*
CCritSec m_Y2RLock; // Acceso serializado.
};
3. Reescribe el constructor en el siguiente formato
//
//// CNullInPlace::Constructor
////////
CYUV2RGBfilter:: CYUV2RGBfilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr):
CTransformFilter(tszName, punk , CLSID_YUV2toRGB24),
m_lBufferRequest(1)
{
ASSERT(tszName);
ASSERT(phr) ;
}// CYUV2RGBfilter
4. Reescribe las cinco funciones virtuales puras de CTransformFilter (el lugar más importante)
HRESULT CheckInputType(const CMediaType *mtIn )
HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType * mtOut);
HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp); (int iPosition, const CMediaType *pMediaType);
HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut
5. Diseñe sus propias funciones privadas para completar ciertas funciones
6. Registrar información de filtro
//Información de registro
//Establecer datos
const AMOVIESETUP_MEDIATYPE
sudPinTypes = { amp; MEDIATYPE_Video // clsMajorType
, amp; MEDIASUBTYPE_NULL }; // clsMinorType
const AMOVIESETUP_PIN
psudPins[] = { L "Entrada" // strName
, FALSE // bRenderizado
, FALSE // bSalida
, FALSE // bCero
, FALSE // bMuchos p>
, amp;CLSID_NULL // clsConnectsToFilter
, L "Salida" // strConnectsToPin
, 1 // nTypes
, amp;sudPinTypes }