Я занимаюсь с DirectShow, и я создал фильтр с интерфейсом. И я создал DLL.
Затем я зарегистрировался в системе, используя comandline (с правами администратора)
regsvr32 TestFilter.dll
и он говорит мне, что это нормально, но когда я пытаюсь использовать в Project, он не распознает.
Что я делаю не так?
IMyInterface.h
// {DB995CEB-DF0E-41aa-8EF9-D75566D9B926}
static const GUID IID_IMyInterface =
{ 0xdb995ceb, 0xdf0e, 0x41aa, { 0x8e, 0xf9, 0xd7, 0x55, 0x66, 0xd9, 0xb9, 0x26 } };
#ifndef __IMYINTERFACE__
#define __IMYINTERFACE__
#ifdef __cplusplus
extern "C" {
#endif
DECLARE_INTERFACE_(IMyInterface, IUnknown)
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// Declarar el mètode de la interfície
STDMETHOD (ChangeColor) (THIS_ bool state) PURE;
///////////////////////////////////////////////////////////////////////////////////////////////////
};
#ifdef __cplusplus
}
#endif
#endif // __IMYINTERFACE__
TestFilter.h
#pragma once
#include "IMyInterface.h"
class CTransFilter :
public IMyInterface,
public CTransformFilter
{
public:
DECLARE_IUNKNOWN;
static CUnknown* WINAPI CreateInstance(LPUNKNOWN lpUnk, HRESULT* phr);
HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);
HRESULT CheckInputType(const CMediaType* mtIn) ;
HRESULT CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut);
HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) ;
HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties);
///////////////////////////////////////////////////////////////////////////////////////////////////
//
STDMETHODIMP ChangeColor(bool state);
///////////////////////////////////////////////////////////////////////////////////////////////////
private:
CTransFilter(LPUNKNOWN lpUnk, HRESULT *phr);
virtual ~CTransFilter(void);
bool enabled;
STDMETHODIMP CTransFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv);
};
TestFilter.cpp
#include <streams.h>
#include "TransFilter.h"
// {0278FE7E-4378-440c-9185-DAA9372349EE}
static const GUID CLSID_TransFilter =
{ 0x278fe7e, 0x4378, 0x440c, { 0x91, 0x85, 0xda, 0xa9, 0x37, 0x23, 0x49, 0xee } };
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_Video, // Major type
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN sudpPins[] =
{
{ L"Input", // Pins string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
},
{ L"Output", // Pins string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
}
};
const AMOVIESETUP_FILTER sudTransFilter =
{
&CLSID_TransFilter, // clsID
L"Trans Filter", // strName
MERIT_DO_NOT_USE, // dwMerit
2, // nPins
sudpPins // lpPin
};
CFactoryTemplate g_Templates[] =
{
{ L"Trans Filter" // name
, &CLSID_TransFilter // CLSID
, CTransFilter::CreateInstance // creation function
, NULL
, &sudTransFilter }, // pointer to filter information
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
//
// DllEntryPoint
//
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
CUnknown* WINAPI CTransFilter::CreateInstance(LPUNKNOWN lpUnk, HRESULT* phr)
{
CTransFilter *pNewObject = new CTransFilter(lpUnk, phr);
if (pNewObject == NULL)
{
*phr = E_OUTOFMEMORY;
}
return pNewObject;
}
// Filter constructor.
CTransFilter::CTransFilter(LPUNKNOWN lpUnk, HRESULT *phr): CTransformFilter(NAME("Trans Filter"), lpUnk, CLSID_TransFilter)
{
enabled = true;
}
CTransFilter::~CTransFilter(void)
{
}
//
//Funció Transform:
//
//Aquesta funció és l'encarregada de fer la transformació. La interfície IMediaSample gestiona
//tota la informació que té el filtre en cada moment de temps (en el nostre cas un frame del vídeo).
//La instància pIn d'aquesta interfície conté la informació que rep el filtre i la instància pOut contindrà
//la informació que volem que rebi el següent filtre.
//Així doncs, el que s'ha de fer en aquesta funció és volcar les dades de pIn a pOut. Per exemple, si es fa
//una còpia exacta de les interfícies aleshores la sortida és la mateixa que l'entrada.
HRESULT CTransFilter::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
//validació que els punters siguin correctes
CheckPointer(pIn,E_POINTER);
CheckPointer(pOut,E_POINTER);
AM_MEDIA_TYPE *mt = &m_pInput->CurrentMediaType();
VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *) mt->pbFormat;
int width,height,num_pixels;
RGBTRIPLE *rgbIn;
RGBTRIPLE *rgbOut;
width = vih->bmiHeader.biWidth;
height = vih->bmiHeader.biHeight;
num_pixels = width*height;
HRESULT hr = pIn->GetPointer((LPBYTE*) &rgbIn);
if(hr != S_OK)
return hr;
hr = pOut->GetPointer((LPBYTE*) &rgbOut);
if(hr != S_OK)
return hr;
if(enabled)
{
///////////////////////////////////////////////////////////////////////////////////////
// Portar a terme la transformació a nivell de píxel
BYTE I;
for(long i=0; i<num_pixels; i++)
{
I = (BYTE) (0.3*rgbIn->rgbtRed + 0.59*rgbIn->rgbtGreen + 0.11*rgbIn->rgbtBlue);
rgbOut->rgbtRed = I;
rgbOut->rgbtGreen = I;
rgbOut->rgbtBlue = I;
rgbOut++;
rgbIn++;
}
///////////////////////////////////////////////////////////////////////////////////////
}
else
{
long length = pIn->GetActualDataLength();
pOut->SetActualDataLength(length);
CopyMemory( (PVOID) rgbOut,(PVOID) rgbIn,length);
}
//aneu amb compte de retornar valors correctes (mireu l'especificació de cadascuna de les funcions)
return S_OK;
}//
//Funció CheckTransform
//
// Aquesta funció valida que el CMediaType d'entrada sigui compatible amb el CMediaType de sortida. Tenint en compte
//la transformació que volem fer.
HRESULT CTransFilter::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
//validació que els punters siguin correctes
CheckPointer(mtIn,E_POINTER);
CheckPointer(mtOut,E_POINTER);
/////////////////////////////////////////////////////////////////////////////////////////
// Comprovem que els tipus siguin els mateixos
// Check the major type.
if (mtOut->majortype == mtIn->majortype)
{
if (mtOut->subtype == mtIn->subtype)
{
return S_OK;
}
}
// Check the subtype and format type.
/////////////////////////////////////////////////////////////////////////////////////////
//aneu amb compte de retornar valors correctes (mireu l'especificació de cadascuna de les funcions)
return VFW_E_TYPE_NOT_ACCEPTED;
}
//
//Funció CheckInputType
//
//Aquesta funció valida que el CMediaType d'entrada sigui correcte
HRESULT CTransFilter::CheckInputType(const CMediaType* mtIn)
{
//validació que els punters siguin correctes
CheckPointer(mtIn,E_POINTER);
/////////////////////////////////////////////////////////////////////////////////////////
// Comprobar que les dades d'entrada són correctes (RGB amb 24 bit per píxel)
if (IsEqualGUID(*mtIn->Type(), MEDIATYPE_Video))
{
if (IsEqualGUID(*mtIn->Subtype(), MEDIASUBTYPE_RGB24))
{
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) mtIn->Format();
if (pvi->bmiHeader.biBitCount == 24) return S_OK;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
return E_FAIL;
}
//
//Funció GetMediaType
//
// Aquesta funció indica el CMediaType que tindrà el pin de sortida del filtre
HRESULT CTransFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
//validació que els punters siguin correctes
CheckPointer(pMediaType,E_POINTER);
// Comprova que pin d'entrada esta connectat. De fet, aquest metode no es crida si
// no es aixi
ASSERT(m_pInput->IsConnected());
if (iPosition < 0)
{
return E_INVALIDARG;
}
if (iPosition == 0)
{
HRESULT hr = m_pInput->ConnectionMediaType(pMediaType);
if (FAILED(hr))
{
return hr;
}
return S_OK;
}
return VFW_S_NO_MORE_ITEMS;
}
//
//Funció DecideBufferSize
//
//Aquesta funció indica quins són els requeriments de memòria de la sortida del filtre.
HRESULT CTransFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties)
{
//validació que els punters siguin correctes
CheckPointer(pAlloc,E_POINTER);
CheckPointer(pProperties,E_POINTER);
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
if (FAILED(hr))
{
return hr;
}
BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
// Calculates byte size of specified bitmap
pProperties->cbBuffer = DIBSIZE(*pbmi) * 1;
pProperties->cBuffers = 1;
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProperties, &Actual);
if (FAILED(hr))
{
return hr;
}
// Even when it succeeds, check the actual result.
if (pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP CTransFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IMyInterface) {
return GetInterface(static_cast<IMyInterface*>(this), ppv);
}
return CBaseFilter::NonDelegatingQueryInterface(riid,ppv);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP: Defines an interface function that returns an HRESULT. It is used for method implementations.
HRESULT CTransFilter::ChangeColor(bool state){
enabled = state;
return enabled;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
И Код, где я хочу его использовать, но include 'IMyInterface.h
не признается
// Prac1_SE.cpp: define el punto de entrada de la aplicaci�n de consola.
//
#include "stdafx.h"#include "DShow.h"#include "IMyInterfaces"
static const GUID IID_IMyInterface =
{ 0xdb995ceb, 0xdf0e, 0x41aa, { 0x8e, 0xf9, 0xd7, 0x55, 0x66, 0xd9, 0xb9, 0x26 } };
static const GUID CLSID_TransFilter =
{ 0x278fe7e, 0x4378, 0x440c, { 0x91, 0x85, 0xda, 0xa9, 0x37, 0x23, 0x49, 0xee } };
void main(void)
{
char change[10];
bool state = false;
IMyInterface *pInterface = NULL;
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
// Create the filter graph manager and query for interfaces.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
/**BW*/
IBaseFilter *pFilterBW;
hr = CoCreateInstance(CLSID_TransFilter,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID*)&pFilterBW);
if( FAILED(hr) ){
printf("ERROR: CoCreateInstance - CLSID_TransFilter\n");
return ;
}
hr = pGraph->AddFilter(pFilterBW,L"CLSID_TransFilter");
if( FAILED(hr) ){
printf("ERROR: AddFilter - CLSID_TransFilter\n");
return ;
}pFilterBW->QueryInterface(IID_IMyInterface,(void **)&pInterface);
printf("Quieres verlo en Blanco y negro [S/s] (cualquier otra respuesta será un NO)\n");
gets_s(change);
if ((strcmp(change,"s")==0) || (strcmp(change,"S")==0) ){
state=true;
}else{
state=false;
}
pInterface->ChangeColor(state);
// Build the graph. IMPORTANT: Change this string to a file on your system.
hr = pGraph->RenderFile(L"..\\Practicas SE\\Prac1_BASE_PRAC2\\chicken.wmv", NULL);
if (SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// Note: Do not use INFINITE in a real application, because it
// can block indefinitely.
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
pFilterBW->Release();
CoUninitialize();
}
И код, где я хочу его использовать, но включаемый IMyInterface.h не распознается
Не распознана должна быть конкретная ошибка компилятора, публикация которой здесь будет полезна.
И, по крайней мере, вы должны предоставить правильное имя файла, чтобы включить:
//#include "IMyInterfaces"#include "IMyInterface.h"
Вам также может понадобиться добавить каталог, содержащий этот файл, в настройки проекта (путь поиска) или явно указать относительный путь, например, например. #include "..\TestFilter\IMyInterface.h"
,
Других решений пока нет …