Search code examples
c#c++dlldirectshowregsvr32

DLL created and registered to system but not accesible from VisualStudio Project


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();
}

Solution

  • 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".