Click to See Complete Forum and Search --> : directshow filter


safileader
March 17th, 2008, 02:11 PM
hello every body
i m a new participent in this forum .
i m working in a very difficult projet for my company
i have to creat a dircetshow filter (in c++) that can send video over network
from a pda with windows mobile (5 or 6) to a pc
so i have written a custom render filter

this is the code any comment?


/////////////////////////////////////////////////////
NetworkSenderFilter.h
/////////////////////////////////////////////////////
#pragma once

#include <streams.h>
#include<initguid.h>
// {A6BE6307-9834-4650-BD22-D0352A75BA5C}
//______________________________________________________________________________________________________________________
DEFINE_GUID(CLSID_NETWORKSENDERFILTER,0xa6be6307, 0x9834, 0x4650, 0xbd, 0x22, 0xd0, 0x35, 0x2a, 0x75, 0xba, 0x5c);
// {FA35B3B2-CD57-4ded-8331-7BBFFDD8D305}
// chge this number in mai,n cpp DEFINE_GUID(, 0x333cb892, 0x7dd3, 0x4fb5, 0xac, 0x9d, 0x73, 0x30, 0xbc, 0xa4, 0x3b, 0x37);
// {95AF2A3A-CE8E-40d4-B5F5-640B6C65AA20}
DEFINE_GUID(IID_IDSNetSender, 0x95af2a3a, 0xce8e, 0x40d4, 0xb5, 0xf5, 0x64, 0xb, 0x6c, 0x65, 0xaa, 0x20);


//______________________________________________________________________________________________________________________

class CNetworkSenderFilter ublic CBaseRenderer, public IDSNetSender
{
public:
DECLARE_IUNKNOWN;//macro permettant d'implementer les 3 methodes q une nouvelle interface doit avoir
char *pName;
IUnknown *r_pUnknown;
HRESULT NoHRESULT;
//______________________________________________________________________________________________________________________
// Override these virtual methods
HRESULT CheckMediaType( const CMediaType *pmt );
HRESULT DoRenderSample( IMediaSample *pMediaSample );
//______________________________________________________________________________________________________________________

// These implement an IPropertyPage interface
STDMETHODIMP SetSocket( SOCKET sock );
// Retrouve l'interface sur le filtre
//STDMETHODIMP NonDelegatingQueryInterface(const IID &riid, void**ppv);
STDMETHODIMP NonDelegatingQueryInterface(REFIID iid, void **ppv);


public:

CNetworkSenderFilter(IN TCHAR *tszName, IN LPUNKNOWN pUnk, OUT HRESULT *phr);
~CNetworkSenderFilter(void);
static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
private:
SOCKET m_sock;
CCritSec m_Lock;


};


//////////////////////////////////////////////////
energifilter.cpp
/////////////////////////////////////////////////

//#include "stdafx.h"
#include "NetworkSenderFilter.h"
static WCHAR g_wszName[] = L"Epstone Network Sender Filter";//nom du filter
//___________________________________________________________________________________________________________________
const AMOVIESETUP_MEDIATYPE sudPinTypes ={&MEDIATYPE_NULL,&MEDIASUBTYPE_NULL};
// Description des pins(un pin)
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*/}};
// Informations pour l'enregistrement du filtre
const AMOVIESETUP_FILTER sudSender ={&CLSID_NETWORKSENDERFILTER/* Filter CLSID*/, g_wszName/* filtre name*/,MERIT_DO_NOT_USE/*Filter merit*/,1/* Number of pins*/, sudpPins /* Pin information*/};
//______________________________________________________________________________________________________________________

CFactoryTemplate g_Templates[] = {{ g_wszName /*Filter Name*/,&CLSID_NETWORKSENDERFILTER /*Filter CLSID*/, CNetworkSenderFilter::CreateInstance /*Filter creation sub*/, NULL /*Initialisation function*/, &sudSender /*Pin information */}};

int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
//______________________________________________________________________________________________________________________

STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2(TRUE);
}

STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
//______________________________________________________________________________________________________________________

extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved)
{
return DllEntryPoint(reinterpret_cast<HINSTANCE>(hDllHandle), dwReason, lpReserved);
}
///////////////////////////////////////////////
/NetworkSenderFilter.cpp
///////////////////////////////////////////////
#include "NetworkSenderFilter.h"
#include <streams.h>
bool Compare_IID(const IID firstguid, const IID secondguid);
#define Compare_GUID utility function

//______________________________________________________________________________________________________________________
CNetworkSenderFilter::CNetworkSenderFilter(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr):CBaseRenderer( CLSID_NETWORKSENDERFILTER, tszName, pUnk, phr )//,IDSNetSender()
{
m_sock = NULL;
//MessageBoxA(NULL, "Creating new instance of CNetworkSenderFilter", "HELLO", MB_ICONINFORMATION);
}

CNetworkSenderFilter::~CNetworkSenderFilter(void)
{
}

//______________________________________________________________________________________________________________________
CUnknown * CNetworkSenderFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
{
*pHr = S_OK;//initialise le pointeur hresult
CNetworkSenderFilter *filter = new CNetworkSenderFilter(NAME("CNetworkSenderFilter"), pUnk, pHr);
if (!filter)
*pHr = E_OUTOFMEMORY;
return filter;
}
//______________________________________________________________________________________________________________________
HRESULT CNetworkSenderFilter:oRenderSample( IMediaSample *pMediaSample ) {
BYTE* data = NULL;
long length = 0;
CheckPointer(pMediaSample,E_POINTER);
pMediaSample->GetPointer(&data);//l echantillon est encaissé
length = pMediaSample->GetSize();
send(m_sock,(char*)data,length,0);

return S_OK;
}
//______________________________________________________________________________________________________________________
HRESULT CNetworkSenderFilter::CheckMediaType( const CMediaType *pmt ) {
return S_OK;
}
//______________________________________________________________________________________________________________________
HRESULT CNetworkSenderFilter::SetSocket(SOCKET thesock) //chge type en STDMETHODIMP et le return return NOERROR;
{
CAutoLock cal(&m_Lock);
m_sock = thesock;
return S_OK;
}
//______________________________________________________________________________________________________________________
/*STDMETHODIMP CNetworkSenderFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{

bool IsIDSNetSender = Compare_IID( riid, IID_IDSNetSender );

if (IsIDSNetSender == true) {
printf("Querying for IDSNetSender interface\r\n");
} else {
printf("Querying for another interface\r\n");
}

if (IsIDSNetSender == true)
{
return GetInterface((IDSNetSender*)this, ppv);
}
// Default: Call parent class method.
// The CUnknown class must be in the inheritance chain.
return CBaseRenderer::NonDelegatingQueryInterface(riid, ppv);
} */
//______________________________________________________________________________________________________________________

STDMETHODIMP CNetworkSenderFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IDSNetSender) {
return GetInterface(static_cast<IDSNetSender*>(this), ppv);
}
return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
}

//*******************************************************

bool Compare_IID(const IID firstguid, const IID secondguid)
{
if ((firstguid.Data1) != (secondguid.Data1)) {return false;}
if ((firstguid.Data2) != (secondguid.Data2)) {return false;}
if ((firstguid.Data3) != (secondguid.Data3)) {return false;}
return true;
}
///////////////////////////////////////////////////
NetworkSenderFilter.def
////////////////////////////////////////////////////
LIBRARY NetworkSenderFilter.DLL
DESCRIPTION 'filtre d emission'
EXPORTS
DllGetClassObject
DllCanUnloadNow
DllRegisterServer
DllUnregisterServer
////////////////////////////////////////////////////////
graph.cpp
////////////////////////////////////////////////////////

//#include "stdafx.h"
#include "NetworkSenderFilter.h"
//#define TestStatus(h,x) if FAILED(h) { printf("%s\n",x); goto EXIT; }//ajout perso pour detcteter erreurs
//DEFINE_GUID (IID_IDSNetSender, 0x333cb892, 0x7dd3, 0x4fb5, 0xac, 0x9d, 0x73, 0x30, 0xbc, 0xa4, 0x3b, 0x37);//lidentifcateur du filtre

int _tmain(int argc, _TCHAR* argv[])
{

//Local variables
IGraphBuilder *pGraph;
ICaptureGraphBuilder2 *pBuilder;
HRESULT hr;
IBaseFilter *pCap = NULL;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pCapEnum = NULL;
IMoniker *pEncodeMoniker = NULL;
IMoniker *pCaptureMoniker = NULL;
IMediaControl *pMediaControl = NULL;
IEnumMoniker *pCompressEnum = NULL;
IBaseFilter *pEncoder = NULL;
IPropertyBag *pPropBag = NULL;
VARIANT varName;
BSTR sName;
_bstr_t codecname("MJPEG Compressor");//Un _bstr_t objet encapsule le type de données BSTR. . La classe gère l'allocation des ressources et deallocation grâce à des appels de fonction SysAllocString et SysFreeString BSTR API et autres le cas échéant. La classe utilise _bstr_t comptage de référence pour éviter une trop généraux.
char* lastcodec;

REFERENCE_TIME rtStart = 0, rtStop = 600000000; //Run for 60 seconds
CoInitialize( NULL );
hr = S_OK;//initialise
//Set up the graph
hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(void **) &pGraph );//creation du filtre graphe
hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,IID_ICaptureGraphBuilder2, (void **) &pBuilder );//creation du graphe de capture
pBuilder->SetFiltergraph( pGraph );//liason entre les 2
//Set up Network Sender

UUID CLSID_NETWORKSENDERFILTER;
UuidFromString( (unsigned char*)"FA35B3B2-CD57-4ded-8331-7BBFFDD8D305", &CLSID_NETWORKSENDERFILTER );

//Initialise the capture device*******************************************************************************

hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void **) &pDevEnum );

hr = pDevEnum->CreateClassEnumerator( CLSID_VideoCompressorCategory, &pCompressEnum, 0 );
int i = 0;
hr = pCompressEnum->Next( 1, &pEncodeMoniker, NULL );
hr = pEncodeMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void **) &pPropBag);
VariantInit( &varName );
hr = pPropBag->Read( L"FriendlyName", &varName, 0 );
sName = varName.bstrVal;
lastcodec = new char[255];
strcpy(lastcodec, "blank");

do {
hr = pCompressEnum->Next( 1, &pEncodeMoniker, NULL );
hr = pEncodeMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void **) &pPropBag);
VariantInit( &varName );
hr = pPropBag->Read( L"FriendlyName", &varName, 0 );
sName = varName.bstrVal;
bstr_t sName_t(sName);
strcpy(lastcodec, (char*) sName_t);
Sleep(500);
} while ( strncmp(lastcodec, "MJPEG Compressor", 5) != 0 );
printf("Got correct filter: %s\r\n", lastcodec);

//Comment this part out for testing without a webcam
hr = pDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pCapEnum, 0 );
hr = pCapEnum->Next( 1, &pCaptureMoniker, NULL );
hr = pCaptureMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**) &pCap);
hr = pGraph->AddFilter( pCap, L"Capture Filter" );
pCaptureMoniker->Release();
pCapEnum->Release();

//Got our capture device

//Get a Compressor Filter
hr = pEncodeMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**) &pEncoder );
hr = pGraph->AddFilter( pEncoder, L"Compressor" );
pEncodeMoniker->Release();
pDevEnum->Release();
pCompressEnum->Release();

//Create our controller****************************************************

hr = pGraph->QueryInterface( IID_IMediaControl, (void**) &pMediaControl );

//Set up the rendering

//Set up Network Sender
// UuidFromString( (unsigned char*)"6DBA0953-4108-4263-93D3-0C9241BD563E", &CLSID_NETWORKSENDERFILTER );
//*******************************************************************************************************
IBaseFilter *pSender = NULL;
IDSNetSender *pNSender = NULL;
CoCreateInstance( CLSID_NETWORKSENDERFILTER, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &pSender );
//Get the IDSNetSender Interface
hr = pSender->QueryInterface( IID_IDSNetSender, (void**) &pNSender );
printf("hr from getting pNSender interface: %li\r\n", hr);
WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);
WSASetLastError(0);
SOCKET sock = socket(AF_INET/**/, SOCK_STREAM/* Establishes a virtual circuit for stream*/, IPPROTO_TCP);/*Socket are characterized by their domain, type and transport protocol. Common domain is
AF INET: address format is host and port number*/
hr = pNSender->SetSocket(sock);
hr = pGraph->AddFilter( pSender, L"Sender" ) ;
//hr = pBuilder->RenderStream( &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL );
hr = pBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap, NULL, pSender );
//*******************************************************************************************************


//And hit the go button
hr = pMediaControl->Run( );
Sleep( 10000 );
pMediaControl->Stop( );
pMediaControl->Release();
pGraph->Release();
pBuilder->Release();

return 0;
}


tell me what are yours opinions
and how can i creat my interface IDSNetSender
((i m using vs 2005))

30cents
July 14th, 2008, 05:30 AM
hi safileader,

i'm also working on a similar project for a final year assignment in my graduating year.

may i know if you have successfully registered this filter?
Is your network filter sending the raw bytes taken by the camera over to the recipient?

regards,
30