c++ - Pass program output to a DirectShow source filter to be picked up by Lync? -
goal
broadly, want accomplish following:
- generate series of images in real-time program
- pass images directshow source filter, registered capture source
- select resulting "virtual webcam" in program lync
the image generation written , must leverage existing framework. working on interface between framework , directshow. current implementation passing images described below.
interfacing
a com interface described in .idl
file, , generated .c
/.h
files included in source filter and, extension, framework module.
additional methods allow specifying media format support , tuning parameters based on rate of image generation.
the passimage
method passes pointer generated image buffer , size of buffer. called framework sink module when receives new data pass.
myinterface.idl
[ object, uuid("46b4bd3c-cd67-4158-bb83-89ea95306a4d"), ] interface iextlivesrc : iunknown { ... hresult passimage ( [in] unsigned long size, [in, size_is(size)] byte **img ); };
directshow source filter
the source filter implemented 2 classes , associated clsid exported dll , registered using regsvr32
. dllregisterserver
method implemented appropriately register com object under clsid_videoinputdevicecategory
.
myfilter.h
class cvsource : public csource { static cunknown *winapi createinstance(lpunknown lpunk, hresult *phr); stdmethodimp queryinterface(refiid riid, void **ppv); // private constructor } class cvsourcestream : public csourcestream , public virtual ikspropertyset , public virtual iamstreamconfig , public virtual iextlivesrc { // constructor, iunknown, ikspropertyset, iamstreamconfig methods ... hresult fillbuffer(imediasample *pms); stdmethodimp passimage(unsigned long size, byte **img); }
note: pin (csourcestream
-derived class) implements interface used pass images. assume buffer size negotiation has been established.
passimage()
stdmethodimp cvsourcestream::passimage(unsigned long size, byte **img) { memcpy_s(this->bufferedimg, size, *img, size); return s_ok; }
fillbuffer()
hresult cvsourcestream::fillbuffer(imediasample *pms) { // set timestamp on imediasample instance ... byte *pdata; pms->getpointer(&pdata); long ldatalen = pms->getsize(); memcpy_s(pdata, ldatalen, this->bufferedimg, ldatalen); return s_ok; }
question
ignoring locking , synchronization moment (i know fillbuffer()
should block until data available), i've made following observations.
- adding generated test sequence of buffers directly
fillbuffer()
leads lync correctly displaying them. - when running program,
passimage()
behaves correctly , buffer instance variable receives correct data. however,fillbuffer()
never seems called when debugging.
based on research i've done, appears issue 2 different processes (my framework program , lync) don't share same data in source filter dll due creating 2 separate instances of filter graph.
what cleanest way lync's instance of filter graph share data images program despositing? i've seen "inter-process communication" tossed around. though i'm not familiar concept, clear list of steps need take towards goal (pipes, sockets, shared memory, registry, etc.)?
links
a similar discussion on msdn forums.
there's discussion of similar problem have not enough concrete details, , don't want post on old thread.
a similar question on stack overflow.
this quite similar have. however, need run new application presumably creates own filter graph.
you have pass data between processes: lync use filter in process, without asking takes data from. , since supposed take data external process, has deal interprocess communication , "somehow connect" remote process data comes from.
there options how can implement "somehow" exactly. prefer using memory mapped files , events/mutexes synchronization. producer process generates data , stores them in mmf, consumer filter inside lync processes reads , delivers generated video.
Comments
Post a Comment