This is a multi-part message in MIME format.
------=_NextPart_000_0046_01C3EBE1.E9CD2310
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
oops... forgot the attachments...
Greetings,
Michael
shared-reality.com
----- Original Message -----
From: "tom de weyer" <tom.deweyer@l ........>
To: <artoolkit@h ..................>
Sent: Monday, February 02, 2004 5:12 PM
Subject: use of firewire camera
> Hello,
>
> I'm a researcher at the luc university in belgium, and we would like to
use
> a firewire camera from pointgrey (firefly2) to capture video for the
> artoolkit. What should I do to enable this? Because at the moment it does
> not recognize the camera. (I'm using the 2.66 on windows xp)
>
>
>
> Thanks very much,
> Tom De Weyer
> research assistant
> LUC-belgium
>
>
------=_NextPart_000_0046_01C3EBE1.E9CD2310
Content-Type: text/plain;
name="DVCam.cpp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="DVCam.cpp"
// DVCam.cpp: implementation of the DVCam class.
//
//////////////////////////////////////////////////////////////////////
#include "ace/OS.h"
#include "ace/Task.h"
#include "ace/Synch_T.h"
#include "ace/Thread_Manager.h"
#include "DVCam.h"
#include <xprtdefs.h> //include this instead of edevdefs
#include "types/SRE_InventorFactory.h"
#include "types/SRE_BaseFactory.h"
#include <CRTDBG.H>
#ifdef DEBUG
#define SAFE_RELEASE(pUnk) if (pUnk) \
{ \
pUnk->Release(); \
pUnk =3D NULL; \
} \
else \
{ \
}
#else
#define SAFE_RELEASE(pUnk) if (pUnk)\
{\
pUnk->Release();\
pUnk =3D NULL;\
}
#endif //DEBUG
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DVCam::DVCam()
{
// init com
CoInitialize(NULL);=20
}
DVCam::~DVCam()
{
printf("--- DVCam \n");
m_stopThread =3D true;=20
DV_CleanUp();
}
void DVCam :: init()
{
// add sinks and attributes=20
namespaceAlias(SRE_Const::XML_SCHEMA_SPEC, "xs");
namespaceAlias(SRE_Const::INVENTOR_NAMESPACE_URI, "inventor");
namespaceAlias(SRE_Const::SRE_BASE_NAMESPACE_URI, "sre");
m_stopThread =3D false;=09
i_trigger =3D addSink("trigger", "sre:Pulse");
a_video =3D addAttribute("video", "sre:Bitmap");
//a_flip =3D addAttribute("flip", "xs:string");
//addAttribute("fps", "xs:int");
a_size =3D addAttribute("size", "inventor:SbVec2s");
=09
// init capture graph
g_bDeviceFound =3DFALSE;
g_pBuilder =3DNULL;
g_pGraphBuilder =3DNULL;
g_pDVCamera =3DNULL;
g_pExtDev =3DNULL;
g_pExtTrans =3DNULL;
g_pTimeReader =3DNULL;
g_pStreamConf =3DNULL;
g_pVideoWindow =3DNULL;
g_pDvDec =3DNULL;
g_pDroppedFrames =3DNULL;
// Filters used in the DirectShow filtergraph
g_pAviSplitter =3DNULL;
g_pInputFileFilter =3DNULL; =20
g_pDVMux =3DNULL;
g_pDVSplitter =3DNULL;
g_pDVCodec =3DNULL;
g_pSmartTee =3DNULL;
g_pDSound =3DNULL;
g_pInfTee =3DNULL;
g_pVideoRenderer =3DNULL;
m_pSampleGrabber =3D NULL;
m_pNullRenderer =3D NULL;
m_mediaCtrl =3D NULL;
if (DV_InitDevice())
{
//If we've gotten this far, all of these components should be =
available
//DV Splitter, DV Muxer, DV Codec is part of QDV
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_DVSplitter, =
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pDVSplitter)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_DVMux, NULL, =
CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pDVMux)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_DVVideoCodec, =
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pDVCodec)));
// Other filters to help in building the graphs
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_AviSplitter, =
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pAviSplitter)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_SmartTee, =
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pSmartTee)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_InfTee, NULL, =
CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pInfTee)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_VideoRenderer, =
NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&g_pVideoRenderer)));
// capturing=20
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_SampleGrabber, NULL, =
CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&m_pSampleGrabber)));
EXECUTE_ASSERT(S_OK =3D=3D CoCreateInstance(CLSID_NullRenderer, NULL, =
CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<PVOID =
*>(&m_pNullRenderer)));
=09
HRESULT hr =3D m_pSampleGrabber->QueryInterface(IID_ISampleGrabber, =
(void **)&m_grabberCtrl);
=09
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaControl, =
reinterpret_cast<PVOID *>(&m_mediaCtrl));
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **) =
&m_mediaEvent);
buildGraph();
}=09
}
void DVCam::DV_CleanUp(void)
{
DV_StopGraph();
DV_DisconnectAll(g_pDVCamera);
SAFE_RELEASE(m_grabberCtrl);
SAFE_RELEASE(m_mediaCtrl);
SAFE_RELEASE(m_mediaEvent);
// release helper dshow interfaces
SAFE_RELEASE(g_pBuilder);
SAFE_RELEASE(g_pExtDev);
SAFE_RELEASE(g_pStreamConf);
SAFE_RELEASE(g_pExtTrans);
SAFE_RELEASE(g_pTimeReader);
SAFE_RELEASE(g_pDroppedFrames);
SAFE_RELEASE(g_pGraphBuilder);
// release the filters of the graph =20
SAFE_RELEASE(g_pDVCamera); =20
SAFE_RELEASE(g_pVideoWindow);
SAFE_RELEASE(g_pInputFileFilter);
SAFE_RELEASE(g_pInfTee);
SAFE_RELEASE(g_pVideoRenderer);
SAFE_RELEASE(g_pAviSplitter);
SAFE_RELEASE(g_pDVSplitter);=20
SAFE_RELEASE(g_pDVCodec);
SAFE_RELEASE(g_pDvDec);
SAFE_RELEASE(g_pDVMux);
SAFE_RELEASE(g_pSmartTee); =20
SAFE_RELEASE(g_pDSound);
SAFE_RELEASE(m_pSampleGrabber);
SAFE_RELEASE(m_pNullRenderer);
CoUninitialize();
}=20
void DVCam :: configure(DOMElement *cfg)
{
// init from XML, set correct size=20
SRE_Component::configure(cfg);
*SRE_InventorFactory::to_SbVec2s(a_size->beginModify()) =3D =
SbVec2s(720, 576);
a_size->endModify();
SRE_BaseFactory::to_Bitmap(a_video->beginModify())->resize(720,576, 3); =
a_video->endModify();
=09
}
// not used right now: update bitmap continuously in extra thread=20
void DVCam :: captureThread(void *data)
{
printf("spawning capture thread \n");
DVCam *cam =3D (DVCam *)data;
//cam->DV_StartGraph();
while (!cam->m_stopThread)
{
HRESULT hr;
long size=3D0;
=09
hr =3D cam->m_grabberCtrl->GetCurrentBuffer(&size, NULL);
printError(hr);
// printf("size is %d \n", size);
SRE_BaseTypes::Bitmap *bm =3D =
SRE_BaseFactory::to_Bitmap(cam->a_video->data());
hr =3D cam->m_grabberCtrl->GetCurrentBuffer(&size, (long =
*)(bm->data));
printError(hr);
}
}
void DVCam :: printError(HRESULT hr, bool ok)
{
if (hr =3D=3D S_OK && ok) printf("OK.\n");
if (hr =3D=3D E_INVALIDARG ) printf("IVALID ARG.\n");
if (hr =3D=3D E_POINTER) printf("NULL POINTER.\n");
if (hr =3D=3D VFW_E_NOT_CONNECTED) printf("NOT CONNECTED.\n");
if (hr =3D=3D VFW_E_WRONG_STATE) printf("WRONG STATE.\n");
}
void DVCam :: onPush(SRE_Event *event, SRE_EventPort *target, =
SRE_EventPort *src)
{
if (target =3D=3D i_trigger)
{
//printf("got trigger \n");
//m_mediaCtrl->Run();
long evCode;
///m_mediaEvent->WaitForCompletion(INFINITE, &evCode);
=09
HRESULT hr;
long size=3D0;
=09
hr =3D m_grabberCtrl->GetCurrentBuffer(&size, NULL);
printError(hr);
// printf("size is %d \n", size);
SRE_BaseTypes::Bitmap *bm =3D =
SRE_BaseFactory::to_Bitmap(a_video->beginModify());
hr =3D m_grabberCtrl->GetCurrentBuffer(&size, (long *)(bm->data));
printError(hr);
=09
// flip=20
static char buf[720*576*3];
int linesize =3D 720*3;
for (int h =3D 0;h!=3Dbm->height/2;h++)
{
unsigned char *low =3D bm->data+(bm->height-h)*linesize;
unsigned char *high =3D bm->data+h*linesize;
memcpy(buf, high, linesize);
=09
memcpy(high, low, linesize);
memcpy(low, buf, linesize);
}
a_video->endModify();
=09
}
}
/*-----------------------------------------------------------------------=
--
Routine: DV_GetGraphBuilder
Purpose: wrapper to get IGraphBuilder interface pointer
Arguments: None
Returns: TRUE if successful
Notes: =20
------------------------------------------------------------------------*=
/
BOOL DVCam::DV_GetGraphBuilder(void)
{
//if we have one, release it, and make a new one
if (g_pGraphBuilder)
{
g_pGraphBuilder->Release();
g_pGraphBuilder =3D NULL;
}=20
HRESULT hr =3D CoCreateInstance(CLSID_FilterGraph, NULL, =
CLSCTX_INPROC, IID_IGraphBuilder, reinterpret_cast<PVOID =
*>(&g_pGraphBuilder));
return (SUCCEEDED(hr)) ? TRUE : FALSE;
}
/*-----------------------------------------------------------------------=
--
Routine: DV_SelectClock
Purpose: Selects the Clock of the Filter sets it to be the clock =
of the Graph
Arguments: Filter to be selected
Returns: HResult as appropriate
Notes: =20
------------------------------------------------------------------------*=
/
HRESULT DVCam::DV_SelectClock(IBaseFilter *pBaseFilter)
{
HRESULT hr =3D S_OK;
IReferenceClock *pRefClock =3D NULL;
IMediaFilter *pMediaFilter =3D NULL;
if(pBaseFilter =3D=3D NULL)
return E_POINTER;
// QI for IReferenceClock on the specified filter
hr =3D pBaseFilter->QueryInterface(IID_IReferenceClock, =
reinterpret_cast<PVOID *> (&pRefClock));
// QI for IMediaFilter from the graph builder
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaFilter, =
reinterpret_cast<PVOID *> (&pMediaFilter));
if(pMediaFilter !=3D NULL && pRefClock !=3D NULL)
{
// set the clock of the specified filter on the filtergraph =
builder
hr =3D pMediaFilter->SetSyncSource(pRefClock);
}
else
hr =3D E_POINTER;
SAFE_RELEASE(pMediaFilter);
SAFE_RELEASE(pRefClock);
return hr;
} =20
/*-----------------------------------------------------------------------=
--
Routine: DV_CleanUp
Purpose: writes values to the registry, releases all used =
interfaces. Uninitializes com and the dshow debug stuff
Arguments: None
Returns: None
Notes: =20
------------------------------------------------------------------------*=
/
BOOL DVCam::buildGraph()
{
HRESULT hr =3D S_OK;
=09
EXECUTE_ASSERT(S_OK =3D=3D g_pGraphBuilder->AddFilter(g_pDVCodec, L"DV =
Codec"));
// Specify what media type to process, to make sure it is connected =
correctly
// We now process full decompressed RGB24 image data
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype =3D MEDIATYPE_Video;
mt.subtype =3D MEDIASUBTYPE_RGB24;
mt.formattype =3D FORMAT_VideoInfo;
hr =3D m_grabberCtrl->SetMediaType(&mt);
// Set working mode as continuous with no buffer
m_grabberCtrl->SetOneShot(FALSE);
m_grabberCtrl->SetBufferSamples(TRUE);
=09
EXECUTE_ASSERT(S_OK =3D=3D g_pGraphBuilder->AddFilter(m_pSampleGrabber, =
L"DV Grabber"));
=09
EXECUTE_ASSERT(S_OK =3D=3D g_pGraphBuilder->AddFilter(m_pNullRenderer, =
L"DV NullRenderer"));
hr =3D g_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, =
&MEDIATYPE_Video, g_pDVCamera, NULL, m_pSampleGrabber);
//if (hr =3D=3D VFW_S_NOPREVIEWPIN) printf("%c \n#### NO PREVIEW ! \n", =
7);
if (hr =3D=3D E_FAIL) printf("%c \n#### RENDER STREAM FAILED ! \n", =
7);
DV_SelectClock(g_pDVCamera);
DV_StartGraph();=09
return hr;
/*
//we need a lot of pins to make this work...
IPin *pAVOut =3D NULL, *pTeeIn =3D NULL, *pTeeOut =3D NULL, *pMuxIn =
=3D NULL, *pTeePreOut =3D NULL, *pSplitIn =3D NULL;
IPin *pVideoOut =3D NULL;
IPin *pSplitVout =3D NULL, *pSplitAout =3D NULL, *pAudIn =3D NULL, =
*pCodecIn =3D NULL, *pCodecOut =3D NULL, *pRenderIn =3D NULL;
//get the camera output pin for video output=20
HRESULT hr =3D S_OK;
hr =3D g_pBuilder->FindPin(g_pDVCamera, PINDIR_OUTPUT, NULL, =
&MEDIATYPE_Video, TRUE, 0, &pVideoOut);
//add the decoder filter, get the smart tee input pin and connect it =
to the DV Cam AV out
if (SUCCEEDED(hr))
{
=20
// find the input & output pins on the dv codec
hr =3D g_pBuilder->FindPin(g_pDVCodec, PINDIR_INPUT, NULL , =
NULL, TRUE, 0, &pCodecIn);
if (SUCCEEDED(hr))
{
hr =3D g_pBuilder->FindPin(g_pDVCodec, PINDIR_OUTPUT, =
NULL , NULL, TRUE, 0, &pCodecOut);
if (SUCCEEDED(hr))
{
}
}
=20
}
return hr;
*/
}
=20
/*-----------------------------------------------------------------------=
--
Routine: DV_InitDevice
Purpose: Enumerates all video devices, and determines if it is a =
DV device. =20
We'll do this by querying for an interface specific =
to DV - in this
case, IAMExtDevice.
Arguments: None
Returns: TRUE if a DV device is found
Notes: Will this solution work all the time. No, but then all =
other solutions are equally unreliable=20
like comparing friendlyname or signal mode or device =
type on the transport.=20
May be the mediatype of the Source filter should =
solve the problem, but then maybe not.
------------------------------------------------------------------------*=
/
BOOL DVCam::DV_InitDevice(void)
{
BOOL bStatus =3D FALSE;
HRESULT hr;
UINT uIndex =3D 0;
ICreateDevEnum *pCreateDevEnum =3D NULL;
// Before we can QI for IAMExtDevice, we need to build a graph and =
add our filter.
=20
// Create Device Enumerator
hr =3D CoCreateInstance(CLSID_SystemDeviceEnum, NULL, =
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<PVOID =
*>(&pCreateDevEnum));
if (SUCCEEDED(hr) )
{
// get the enumerator for videoinput devices
IEnumMoniker *pEm;
hr =3D =
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, =
&pEm, 0);
if (SUCCEEDED(hr) && pEm)
{
pCreateDevEnum->Release();
{
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
//loop while we can still enumerate, the enumeration =
succeeds, and while we have'nt yet found a dv camera
while ( S_OK =3D=3D (hr =3D pEm->Next(1, &pM, =
&cFetched)) && FALSE =3D=3D bStatus )
{
// getting the propert page to get the device name
IPropertyBag *pBag;
hr =3D pM->BindToStorage(0, 0, IID_IPropertyBag, =
reinterpret_cast<PVOID *>(&pBag));
if ( SUCCEEDED(hr) )
{
VARIANT var;
var.vt =3D VT_BSTR;
hr =3D pBag->Read(L"FriendlyName", &var, NULL);
if ( SUCCEEDED(hr) )
{
//here, we'll save the device name
#ifndef UNICODE
WideCharToMultiByte(CP_ACP, 0, var.bstrVal, =
-1, g_DeviceName, 512, NULL, NULL);
#else
lstrcpyW(g_DeviceName, var.bstrVal);
#endif //UNICODE =20
printf("Device Found:\t%s\n", g_DeviceName);
//DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_SUCCINCT, TEXT("Device =
Found:\t%s"), g_DeviceName);
SysFreeString(var.bstrVal);
// Get the filter of video input device
hr =3D pM->BindToObject(0, 0, =
IID_IBaseFilter, reinterpret_cast<PVOID *>(&g_pDVCamera));
if ( g_pDVCamera =3D=3D NULL )
{
printf("Error %x: Cannot create video =
capture filter\n", hr);
return FALSE;
}
else
{ // get the graph builder & capture graph =
builder to QI
if (DV_GetGraphBuilder())
{
hr =3D =
CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC, =
(REFIID)IID_ICaptureGraphBuilder2,
reinterpret_cast<PVOID =
*>(&g_pBuilder));
if (SUCCEEDED(hr))
{
hr =3D =
g_pBuilder->SetFiltergraph(g_pGraphBuilder);
if (SUCCEEDED(hr))
{
//add the DV cam to the =
graph
hr =3D =
g_pGraphBuilder->AddFilter(g_pDVCamera, var.bstrVal);
if (SUCCEEDED(hr))
{ // QI for IAMExtDevice
hr =3D =
g_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
=
&MEDIATYPE_Video, =20
=
g_pDVCamera,IID_IAMExtDevice,=20
=
reinterpret_cast<PVOID*>(&g_pExtDev));
if (SUCCEEDED(hr))
{
//we have a DV =
camera
printf("We Have a DV =
camera\n");
bStatus =3D TRUE;
}=20
else
{
printf("This is not =
a DV camera\n");
//release our =
interfaces
=
SAFE_RELEASE(g_pGraphBuilder);
=
SAFE_RELEASE(g_pBuilder);
=
SAFE_RELEASE(g_pDVCamera);
} =
=20
}=20
else
{
printf("AddFilter failed =
hr. =3D 0x%x\n", hr);
}
}=20
else
{
printf("SetFilterGraph =
failed. hr =3D 0x%x\n", hr);
}
}
else
{
printf("CoCreateInstance failed =
(ICaptureGraphbuilder2). hr =3D 0x%x\n", hr);
}=20
}
else
{
printf("DV_GetGraphBuilder =
failed\n");
}=20
=20
} //end g_pDVCamera =3D=3D NULL
=20
} //end SUCCEEDED(hr)
pBag->Release();
}
pM->Release();
uIndex++;
}
pEm->Release();
}
}
else
{
// no interesting devices
printf("CreateClassEnumerator failed or Enumerator was not =
initialized. hr =3D 0x%c\n", hr);
//MBOX(TEXT("There are no video devices installed"));
}=20
}
return bStatus;
}=20
/*-----------------------------------------------------------------------=
--
Routine: DV_GetDVMode
Purpose: Determines camera mode using =
IAMExtDevice::GetCapability()
Arguments: None
Returns: Current mode of camera device
Notes: =20
------------------------------------------------------------------------*=
/
DVCam::DV_MODE DVCam::DV_GetDVMode(void)
{
HRESULT hr =3D S_OK;
LONG lDeviceType =3D 0;
ASSERT(g_pExtDev);
// Query the Device Type Capability
hr =3D g_pExtDev->GetCapability(ED_DEVCAP_DEVICE_TYPE, &lDeviceType, =
0);
if (SUCCEEDED(hr))
{
switch (lDeviceType)
{
case 0 :
//device type is unknown
g_CurrentMode =3D UnknownMode;
break;
case ED_DEVTYPE_VCR :
g_CurrentMode =3D VcrMode;
break;
case ED_DEVTYPE_CAMERA :
g_CurrentMode =3D CameraMode;
break;
default :
printf("GetCapability returned an unknown device type - =
0x%x", lDeviceType);
break;
}=20
}
return g_CurrentMode;
}=20
/*-----------------------------------------------------------------------=
--
Routine: DV_StartGraph
Purpose: Starts the Filter Graph=20
Arguments: None
Returns: HResult as appropriate
Notes: =20
------------------------------------------------------------------------*=
/
HRESULT DVCam::DV_StartGraph(void)
{
HRESULT hr;
IMediaControl *pMC =3D NULL;
// QI for the media control=20
if(!g_pGraphBuilder)
return S_FALSE;
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaControl, =
reinterpret_cast<PVOID *>(&pMC));
if (SUCCEEDED(hr))
{
// start the graph
hr =3D pMC->Run();
if ( FAILED(hr))
{
printf("IMediaControl::Run failed (0x%x)", hr);
// stop parts that ran
pMC->Stop();
}
SAFE_RELEASE(pMC);
}
return hr;
}
/*-----------------------------------------------------------------------=
--
Routine: DV_PauseGraph
Purpose: Starts the Filter Graph=20
Arguments: None
Returns: HResult as appropriate
Notes: =20
------------------------------------------------------------------------*=
/
HRESULT DVCam::DV_PauseGraph(void)
{
HRESULT hr;
IMediaControl *pMC =3D NULL;
=20
if(!g_pGraphBuilder)
return S_FALSE;
// QI for the media control=20
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaControl, =
reinterpret_cast<PVOID *>(&pMC));
if (SUCCEEDED(hr))
{
// Pause the graph
hr =3D pMC->Pause();
if ( FAILED(hr))
{
printf("IMediaControl::Pause failed (0x%x)", hr);
// stop parts that ran
pMC->Stop();
}
SAFE_RELEASE(pMC);
}
return hr;
}
/*-----------------------------------------------------------------------=
--
Routine: DV_StopGraph
Purpose: Starts the Filter Graph=20
Arguments: None
Returns: HResult as appropriate
Notes: =20
------------------------------------------------------------------------*=
/
HRESULT DVCam::DV_StopGraph(void)
{
HRESULT hr;
IMediaControl *pMC =3D NULL;
if(!g_pGraphBuilder)
return S_FALSE;
//stop the current graph
hr =3D g_pGraphBuilder->QueryInterface(IID_IMediaControl, =
reinterpret_cast<PVOID *>(&pMC));
if (SUCCEEDED(hr))
{
hr =3D pMC->Stop();
SAFE_RELEASE(pMC);
}
return hr;
}
/*-----------------------------------------------------------------------=
--
Routine: DV_SaveGraph
Purpose: Save the filter graph into a *.grf file
Arguments: FileName
Returns: HRESULT as appropriate
Notes: =20
------------------------------------------------------------------------*=
/
HRESULT DVCam :: DV_SaveGraph(TCHAR* sGraphFile)
{
IStorage * pStorage =3D NULL;
IStream * pStream =3D NULL;
IPersistStream * pPersistStream =3D NULL;
HRESULT hr =3D S_OK;
if(g_pGraphBuilder =3D=3D NULL || sGraphFile =3D=3D NULL)
return E_FAIL;
#ifndef UNICODE
WCHAR swGraphFile[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, sGraphFile, -1, swGraphFile, =
MAX_PATH);
// Either Open or Create the *.GRF file
hr =3D StgOpenStorage( swGraphFile, NULL, STGM_TRANSACTED | =
STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
if ( STG_E_FILENOTFOUND =3D=3D hr )
hr =3D StgCreateDocfile( swGraphFile, STGM_CREATE | =
STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE , NULL , =
&pStorage);
#else
// Either Open or Create the *.GRF file
hr =3D StgOpenStorage( sGraphFile, NULL, STGM_TRANSACTED | =
STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage );
if ( STG_E_FILENOTFOUND =3D=3D hr )
hr =3D StgCreateDocfile( sGraphFile, STGM_CREATE | =
STGM_TRANSACTED | STGM_2READWRITE | STGM_SHARE_EXCLUSIVE , NULL , =
&pStorage);
#endif
if ( SUCCEEDED(hr) )
hr =3D pStorage->CreateStream( L"ActiveMovieGraph", STGM_WRITE | =
STGM_CREATE | STGM_SHARE_EXCLUSIVE, NULL, NULL, &pStream );
// Persist the stream, save & commit to disk
if ( SUCCEEDED(hr) )
hr =3D g_pGraphBuilder->QueryInterface( IID_IPersistStream, =
(void **) &pPersistStream );
if ( SUCCEEDED(hr) )
hr =3D pPersistStream->Save(pStream, TRUE);
if ( SUCCEEDED(hr) )
hr =3D pStorage->Commit( STGC_DEFAULT );
if ( SUCCEEDED(hr) )
printf("Save current Filter Graph to GRF file succeded");
else
{
MessageBox( NULL, "Save GRF file failed", "DVApp", =
MB_ICONEXCLAMATION | MB_OK );
printf("Save current Filter Graph to GRF file failed");
}
SAFE_RELEASE(pStorage);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pPersistStream);
return hr;
}
/*-----------------------------------------------------------------------=
--
Routine: DV_DisconnectAll
Purpose: Disconnects all pins in a graph (downstream from pBF) =20
Arguments: pointer to the filter to disconnect pins from (downstream =
only)
Returns: None
Notes: This is the recursive nuke downstream routine from amcap
------------------------------------------------------------------------*=
/
void DVCam::DV_DisconnectAll(IBaseFilter *pBF)
{
IPin *pP, *pTo;
ULONG u;
IEnumPins *pins =3D NULL;
PIN_INFO pininfo;
ASSERT(g_pGraphBuilder);
/* DV_LogOut(LOG_PRIORITY_INFO, LOG_LEVEL_VERBOSE, =
TEXT("Disconnecting Pins..."));*/
=20
HRESULT hr =3D pBF->EnumPins(&pins);
pins->Reset();
while ( hr =3D=3D NOERROR )
{
hr =3D pins->Next(1, &pP, &u);
if ( hr =3D=3D S_OK && pP )
{
pP->ConnectedTo(&pTo);
if ( pTo )
{
hr =3D pTo->QueryPinInfo(&pininfo);
if ( hr =3D=3D NOERROR )
{
if ( pininfo.dir =3D=3D PINDIR_INPUT )
{
DV_DisconnectAll(pininfo.pFilter);
hr =3D g_pGraphBuilder->Disconnect(pTo);
hr =3D g_pGraphBuilder->Disconnect(pP);
//always leave the Camera filter in the graph
//if the base filter is a file,the camera is =
downstream
if (pininfo.pFilter !=3D g_pDVCamera)
{
hr =3D =
g_pGraphBuilder->RemoveFilter(pininfo.pFilter);
}
}
ASSERT(pininfo.pFilter);
SAFE_RELEASE(pininfo.pFilter);
}
ASSERT(pTo);
SAFE_RELEASE(pTo);
}
ASSERT(pP);
SAFE_RELEASE(pP);
}
}
if ( pins )
SAFE_RELEASE(pins);
}=20
------=_NextPart_000_0046_01C3EBE1.E9CD2310
Content-Type: text/plain;
name="DVCam.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="DVCam.h"
// DVCam.h: interface for the DVCam class.
//
//////////////////////////////////////////////////////////////////////
#if =
!defined(AFX_DVCAM_H__2E32EA5E_C0C6_41BE_861A_894F2B92E620__INCLUDED_)
#define AFX_DVCAM_H__2E32EA5E_C0C6_41BE_861A_894F2B92E620__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <dshow.h>
#include <qedit.h>
#include <stdio.h>
#include "sca/SRE_Component.h"
#include <streams.h>
// Link to Strmbase.lib
// this is the capture callback called from DShow
class DVGrabCB: public CUnknown, public ISampleGrabberCB
{
public:
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if( riid =3D=3D IID_ISampleGrabberCB )
{
return GetInterface((ISampleGrabberCB*)this, ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
// ISampleGrabberCB methods
STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
{
printf("Sample time: %f\n", SampleTime);
return S_OK;
}
STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer, long =
BufferLen)
{
return E_NOTIMPL;
}
=20
// Constructor
DVGrabCB( ) : CUnknown("SGCB", NULL)
{ }
};
// component for firewire / digicam support=20
class DVCam : public SRE_Component
{
public:
SRE_CREATE(DVCam)
DVCam();
virtual ~DVCam();
//---- overloaded from SRE_Component=20
void configure(DOMElement *cfg);
// init sinks, sources & attributes=20
void init();
// called whenever a sink or attribute gets new data=20
void onPush(SRE_Event *event, SRE_EventPort *target, SRE_EventPort =
*src);
protected:
// triggers video push into sr:environment
SRE_Sink *i_trigger;
// contains video bitmap & size=20
SRE_Attribute *a_video, *a_size;
// init capture graph
BOOL buildGraph();
// funcs from DV-App, dshow example=20
BOOL DV_InitDevice(void);
BOOL DV_GetGraphBuilder(void);
HRESULT DV_SelectClock(IBaseFilter *pBaseFilter);
void DV_CleanUp(void);
static void printError(HRESULT hr, bool ok=3Dfalse);
static void captureThread(void *);
bool m_stopThread;
//track device mode or active=20
enum DV_MODE
{
CameraMode =3D 0L,
VcrMode =3D 1L,
UnknownMode =3D 2L
};=20
DV_MODE g_CurrentMode;
DV_MODE DV_GetDVMode(void);
HRESULT DV_StopGraph(void);
HRESULT DV_StartGraph(void);
HRESULT DV_PauseGraph(void);
HRESULT DV_SaveGraph(TCHAR* sGraphFile);
void DV_DisconnectAll(IBaseFilter *pBF);
// device notification globals
TCHAR g_DeviceName[512];
BOOL g_bDeviceFound;
// DirectShow interfaces to help build the filter graph & control the =
capture device
DVGrabCB *m_grabCB;
ICaptureGraphBuilder2 *g_pBuilder ;
IGraphBuilder *g_pGraphBuilder ;
IBaseFilter *g_pDVCamera ;
IAMExtDevice *g_pExtDev ;
IAMExtTransport *g_pExtTrans ;
IAMTimecodeReader *g_pTimeReader ;
IAMStreamConfig *g_pStreamConf ;
IVideoWindow *g_pVideoWindow ;
IIPDVDec *g_pDvDec ;
IAMDroppedFrames *g_pDroppedFrames ;
IMediaControl *m_mediaCtrl;
IMediaEvent *m_mediaEvent;
// Filters used in the DirectShow filtergraph
IBaseFilter *g_pAviSplitter ;
IBaseFilter *g_pInputFileFilter ; =20
IBaseFilter *g_pDVMux ;
IBaseFilter *g_pDVSplitter ;
IBaseFilter *g_pDVCodec ;
IBaseFilter *g_pSmartTee ;
IBaseFilter *g_pDSound ;
IBaseFilter *g_pInfTee ;
IBaseFilter *g_pVideoRenderer ;
// for capturing=20
IBaseFilter *m_pSampleGrabber;
IBaseFilter *m_pNullRenderer;
ISampleGrabber *m_grabberCtrl;
};
#endif // =
!defined(AFX_DVCAM_H__2E32EA5E_C0C6_41BE_861A_894F2B92E620__INCLUDED_)
------=_NextPart_000_0046_01C3EBE1.E9CD2310--
|