DirectShow Filter (COM Issues)

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hi,

I am trying to write a DirectShow filter to allow a programmer to send data
being sent in a stream over the network. I have run into problems creating an
interface to allow the programmer to set a socket to send the data over.
Unfortunately, when I try to query for this interface, I get a NULL pointer,
but functions involving the interface still seem to work. Additionally, when
they do work, setting the socket does not work, and the socket always seems
to be a certain random number. Excerpts of code follow.

DS Network Sender.CPP:

#include "stdafx.h"
#include "DirectShow Network Sender.h"
;

bool Compare_IID(const IID firstguid, const IID secondguid); //Forward
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);
}

HRESULT CNetworkSenderFilter::CheckMediaType( const CMediaType *pmt ) {
return S_OK;
}

HRESULT CNetworkSenderFilter::DoRenderSample( IMediaSample *pMediaSample ) {
BYTE* data = NULL;
long length = 0;

CheckPointer(pMediaSample, E_POINTER);

pMediaSample->GetPointer( &data );
length = pMediaSample->GetSize();

send( m_sock, (char*) data, length, 0 );

return S_OK;
}

HRESULT CNetworkSenderFilter::SetSocket( SOCKET thesock ) {
CAutoLock cal(&m_Lock);

m_sock = thesock;

return S_OK;
}

STDMETHODIMP CNetworkSenderFilter::NonDelegatingQueryInterface(REFIID riid,
void **ppv)
{

CheckPointer(ppv,E_POINTER);

if (riid == IID_IDSNetSender) {
return GetInterface((IDSNetSender *) this, ppv);
} else {
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;
}

DS NETWORK SENDER.H:

#pragma once

#include "stdafx.h"

//#define CLSID_NETWORKSENDERFILTER GUID_NULL

// GUID {6DBA0953-4108-4263-93D3-0C9241BD563E}
DEFINE_GUID( CLSID_NETWORKSENDERFILTER, 0x6dba0953, 0x4108, 0x4263, 0x93,
0xd3, 0xc, 0x92, 0x41, 0xbd, 0x56, 0x3e );
DEFINE_GUID( IID_IDSNetSender, 0x333cb892, 0x7dd3, 0x4fb5, 0xac, 0x9d, 0x73,
0x30, 0xbc, 0xa4, 0x3b, 0x37);

class CNetworkSenderFilter: public CBaseRenderer, public IDSNetSender {
public:

DECLARE_IUNKNOWN;

char *pName;
IUnknown *r_pUnknown;
HRESULT NoHRESULT;
~CNetworkSenderFilter( ) /*~CBaseRenderer()*/ {}
HRESULT CheckMediaType( const CMediaType *pmt );
HRESULT DoRenderSample( IMediaSample *pMediaSample );
STDMETHODIMP SetSocket( SOCKET sock );
STDMETHODIMP NonDelegatingQueryInterface(const IID &riid, void**ppv);
static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
//CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
private:
SOCKET m_sock;
CNetworkSenderFilter(IN TCHAR *tszName, IN LPUNKNOWN pUnk, OUT HRESULT *phr);
CCritSec m_Lock;
}

COM STUFF.CPP:

#include "stdafx.h"
#include "DirectShow Network Sender.h"
;
static WCHAR g_wszName[] = L"Epstone Network Sender Filter";

// Setup information
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL, // 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
}
};

const AMOVIESETUP_FILTER sudSender =
{
&CLSID_NETWORKSENDERFILTER, // Filter CLSID
g_wszName, // String name
MERIT_DO_NOT_USE, // Filter merit
1, // Number of pins
sudpPins // Pin information
};

// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance

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]);



CUnknown * WINAPI CNetworkSenderFilter::CreateInstance(LPUNKNOWN pUnk,
HRESULT *pHr)
{
*pHr = S_OK;

CNetworkSenderFilter *filter = new
CNetworkSenderFilter(NAME("CNetworkSenderFilter"), pUnk, pHr);

if (!filter)
*pHr = E_OUTOFMEMORY;

return filter;
}


STDAPI DllRegisterServer()
{

return AMovieDllRegisterServer2(TRUE);

}
STDAPI DllUnregisterServer()
{

return AMovieDllRegisterServer2(FALSE);

}

// If we declare the correct C runtime entrypoint and then forward it to the
DShow base
// classes we will be sure that both the C/C++ runtimes and the base classes
are initialized
// correctly
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);
}

TEST.CPP:

// Webcam Capture Test.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"
#include "DSNetSender_h.h"

DEFINE_GUID( IID_IDSNetSender, 0x333cb892, 0x7dd3, 0x4fb5, 0xac, 0x9d, 0x73,
0x30, 0xbc, 0xa4, 0x3b, 0x37);

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");
char* lastcodec;

REFERENCE_TIME rtStart = 0, rtStop = 600000000; //Run for 60 seconds

CoInitialize( NULL );

hr = S_OK;

//Set up the graph
hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,
(void **) &pGraph );

hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **) &pBuilder );

pBuilder->SetFiltergraph( pGraph );


//Set up Network Sender

UUID CLSID_NETWORKSENDERFILTER;

UuidFromString( (unsigned char*)"6DBA0953-4108-4263-93D3-0C9241BD563E",
&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

// UUID CLSID_NETWORKSENDERFILTER;

// 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, IPPROTO_TCP);

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


Any help would be appreciated.

Andrew Garrett,
Epstone Networks
--

Andrew Garrett
Epstone Networks
.



Relevant Pages

  • Re: March 29, 2006 total eclipse - IT admins WORST NIGHTMARE
    ... and NewsProxy is the answer for that. ... > Comcast news server. ... simply filters out what I dont want on the network. ... NewsProxy - Network level killfile and content filter for Usenet. ...
    (comp.security.firewalls)
  • "Catastrophic failure" in directshow graph
    ... The filter I'm writing is a "Heartbeat Filter" that keeps data flowing ... even if no data is arriving on the input pin. ... HeartbeatFilter(LPUNKNOWN punk, HRESULT *phr); ... virtual STDMETHODIMP Pause; ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: FIREWALL CHECK
    ... at all (windows firewall). ... The job of a real FW, which I don't consider some 3rd party personal FW/packet filter or even Vista's FW/packet filter to be a FW is not to stop malware. ... A packet filtering FW router, FW appliance or host based software FW running on a secured gateway computer jobs are not to be stopping a malware program running on some computer. ... In either case, it must have at least two network interfaces, one for the network it is intended to protect, and one for the network it is exposed to. ...
    (microsoft.public.windows.vista.security)
  • Help! Once I using the transform filter, It cant record
    ... The media type of the capture pin is RGB565, so the transform filter ... CMyOwnTransformFilter::CMyOwnTransformFilter(LPUNKNOWN pUnk, HRESULT ... VIDEOINFOHEADER *pVihIn; ...
    (microsoft.public.pocketpc.developer)
  • Re: fields extraction
    ... This filter takes 24bit interlaced video and extracts two fields from each ... HRESULT CMyFilter3a::CheckTransform(const CMediaType* mtIn, const ... HRESULT hr = NOERROR; ...
    (microsoft.public.win32.programmer.directx.video)