I'm doing some practice with DirectShow, and I have created a filter with interface. And I have created the DLL.
Then I registered to system using in comandline (with admins permissions)
regsvr32 TestFilter.dll
and It tells me that it's ok, but when I try to use in Project it dont recognise.
What i'm doing wrong?
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;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
And the Code where I want to use it, but the include 'IMyInterface.h
is not recognised
// 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();
}
And the Code where I want to use it, but the include 'IMyInterface.h is not recognized
Not recognized should have a specific compiler error, posting of which here would be helpful.
And at the very least you should provide correct file name to include:
//#include "IMyInterfaces"
#include "IMyInterface.h"
You might also need to add the directory containing this file to the project settings (search path), or specify relative path explicitly including e.g. #include "..\TestFilter\IMyInterface.h"
.