diff --git a/doc/makepanda/makepanda.py b/doc/makepanda/makepanda.py index 5d83e2f7a3..0257e0d03b 100755 --- a/doc/makepanda/makepanda.py +++ b/doc/makepanda/makepanda.py @@ -730,6 +730,7 @@ def ChooseCompiler(): AddToPathEnv("INCLUDE", vcdir + "VC\\include") AddToPathEnv("LIB", vcdir + "VC\\lib") AddToPathEnv("INCLUDE", platsdk + "include") + AddToPathEnv("INCLUDE", platsdk + "include\\atl") AddToPathEnv("LIB", platsdk + "lib") COMPILER="MSVC" THIRDPARTYLIBS="thirdparty/win-libs-vc8/" @@ -1375,6 +1376,7 @@ def CompileLink(dll, obj, opts, ldef): if (opts.count("WINGDI")): cmd = cmd + " gdi32.lib" if (opts.count("ADVAPI")): cmd = cmd + " advapi32.lib" if (opts.count("GLUT")): cmd = cmd + " opengl32.lib glu32.lib" + if (opts.count("DIRECTSHOW")): cmd = cmd + " strmiids.lib quartz.lib odbc32.lib odbccp32.lib" if (PkgSelected(opts,"PNG")): cmd = cmd + ' ' + THIRDPARTYLIBS + 'png/lib/libpandapng.lib' if (PkgSelected(opts,"JPEG")): cmd = cmd + ' ' + THIRDPARTYLIBS + 'jpeg/lib/libpandajpeg.lib' if (PkgSelected(opts,"TIFF")): cmd = cmd + ' ' + THIRDPARTYLIBS + 'tiff/lib/libpandatiff.lib' @@ -2587,7 +2589,7 @@ EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libtext.in', obj='libtext_igate.obj', # IPATH=['panda/src/movies'] -OPTS=['BUILDING_PANDA', 'FFMPEG'] +OPTS=['BUILDING_PANDA', 'FFMPEG', 'DX9', 'DIRECTSHOW'] EnqueueCxx(ipath=IPATH, opts=OPTS, src='movies_composite1.cxx', obj='movies_composite1.obj') EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libmovies.in', obj='libmovies_igate.obj', src='panda/src/movies', module='panda', library='libmovies', @@ -2687,7 +2689,7 @@ if (OMIT.count("VRPN")==0): # IPATH=['panda/metalibs/panda'] -OPTS=['BUILDING_PANDA', 'ZLIB', 'VRPN', 'JPEG', 'PNG', 'TIFF', 'ZLIB', 'NVIDIACG', 'OPENSSL', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM', 'FFMPEG', 'ARTOOLKIT'] +OPTS=['BUILDING_PANDA', 'ZLIB', 'VRPN', 'JPEG', 'PNG', 'TIFF', 'ZLIB', 'NVIDIACG', 'OPENSSL', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM', 'FFMPEG', 'DIRECTSHOW', 'ARTOOLKIT'] INFILES=['librecorder.in', 'libpgraph.in', 'libcull.in', 'libgrutil.in', 'libchan.in', 'libpstatclient.in', 'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libpipeline.in', 'libevent.in', 'libgobj.in', 'libgsgbase.in', 'liblinmath.in', 'libmathutil.in', 'libparametrics.in', @@ -2746,7 +2748,7 @@ EnqueueLink(opts=OPTS, dll='libpanda.dll', obj=OBJFILES, xdep=[ # IPATH=['panda/src/skel'] -OPTS=['BUILDING_PANDASKEL', 'ARTOOLKIT'] +OPTS=['BUILDING_PANDASKEL', 'ADVAPI'] EnqueueCxx(ipath=IPATH, opts=OPTS, src='skel_composite.cxx', obj='skel_composite.obj') EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libskel.in', obj='libskel_igate.obj', src='panda/src/skel', module='pandaskel', library='libskel', @@ -2756,7 +2758,7 @@ EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libskel.in', obj='libskel_igate.obj', # DIRECTORY: panda/metalibs/panda # -OPTS=['BUILDING_PANDASKEL', 'ARTOOLKIT', 'ADVAPI'] +OPTS=['BUILDING_PANDASKEL', 'ADVAPI'] EnqueueImod(ipath=IPATH, opts=OPTS, obj='libpandaskel_module.obj', module='pandaskel', library='libpandaskel', files=["libskel.in","libmovies.in"]) EnqueueLink(dll='libpandaskel.dll', opts=OPTS, obj=[ diff --git a/panda/src/movies/config_movies.cxx b/panda/src/movies/config_movies.cxx index b1043110f4..fb7acb61cf 100644 --- a/panda/src/movies/config_movies.cxx +++ b/panda/src/movies/config_movies.cxx @@ -18,6 +18,7 @@ #include "config_movies.h" #include "dconfig.h" +#include "webcamVideo.h" #ifdef HAVE_FFMPEG #include "avcodec.h" @@ -52,6 +53,8 @@ init_libmovies() { MovieAudioCursor::init_type(); InkblotVideo::init_type(); InkblotVideoCursor::init_type(); + WebcamVideo::init_type(); + WebcamVideo::init_cursor_type(); #ifdef HAVE_FFMPEG FfmpegVideo::init_type(); FfmpegVideoCursor::init_type(); diff --git a/panda/src/movies/movies_composite1.cxx b/panda/src/movies/movies_composite1.cxx index a793e52b56..ca9d659fd1 100644 --- a/panda/src/movies/movies_composite1.cxx +++ b/panda/src/movies/movies_composite1.cxx @@ -15,4 +15,6 @@ #include "ffmpegVirtualFile.cxx" +#include "webcamVideo.cxx" + #include "config_movies.cxx" diff --git a/panda/src/movies/webcamVideo.I b/panda/src/movies/webcamVideo.I new file mode 100644 index 0000000000..ea3dccca49 --- /dev/null +++ b/panda/src/movies/webcamVideo.I @@ -0,0 +1,18 @@ +// Filename: webcamVideo.I +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/movies/webcamVideo.cxx b/panda/src/movies/webcamVideo.cxx new file mode 100644 index 0000000000..f2c591cd10 --- /dev/null +++ b/panda/src/movies/webcamVideo.cxx @@ -0,0 +1,70 @@ +// Filename: webcamVideo.cxx +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2007, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "webcamVideo.h" +#include "pandabase.h" +#include "movieVideoCursor.h" + +TypeHandle WebcamVideo::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::Constructor +// Access: Public +// Description: The parameters x,y, and fps are suggestions. The +// webcam will match these as closely as it can, but +// of course, there are no guarantees. +//////////////////////////////////////////////////////////////////// +WebcamVideo:: +WebcamVideo(const string &dev, int x, int y, int fps) : + MovieVideo("webcam"), + _specified_device(dev), + _specified_x(x), + _specified_y(y), + _specified_fps(y) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideo:: +~WebcamVideo() { +} + +//////////////////////////////////////////////////////////////////// +// The rest of this file is OS-dependent. +// We include the appropriate version depending +// the user's compile-configuration. +//////////////////////////////////////////////////////////////////// + +#if defined(HAVE_DX9) + +#include "webcamVideoDX.cxx" + +#elif defined(HAVE_VIDEO4LINUX) + +#include "webcamVideoV4L.cxx" + +#else + +#include "webcamVideoNull.cxx" + +#endif + diff --git a/panda/src/movies/webcamVideo.h b/panda/src/movies/webcamVideo.h new file mode 100644 index 0000000000..5f07046d89 --- /dev/null +++ b/panda/src/movies/webcamVideo.h @@ -0,0 +1,70 @@ +// Filename: webcamVideo.h +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef WEBCAMVIDEO_H +#define WEBCAMVIDEO_H + +#include "movieVideo.h" + +//////////////////////////////////////////////////////////////////// +// Class : WebcamVideo +// Description : Allows you to open a webcam or other video capture +// device as a video stream. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA_MOVIES WebcamVideo : public MovieVideo { + + PUBLISHED: + WebcamVideo(const string &dev, int x=640, int y=480, int fps=24); + virtual ~WebcamVideo(); + + static int get_num_devices(); + static string get_device_name(int n); + + virtual PT(MovieVideoCursor) open(); + + private: + string _specified_device; + int _specified_x; + int _specified_y; + int _specified_fps; + friend class WebcamVideoCursor; + +public: + static void init_cursor_type(); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + MovieVideo::init_type(); + register_type(_type_handle, "WebcamVideo", + MovieVideo::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "webcamVideo.I" + +#endif diff --git a/panda/src/movies/webcamVideoDX.cxx b/panda/src/movies/webcamVideoDX.cxx new file mode 100644 index 0000000000..865b0194a6 --- /dev/null +++ b/panda/src/movies/webcamVideoDX.cxx @@ -0,0 +1,479 @@ +// Filename: webcamVideoDX.cxx +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2007, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// +// +// This code was created by studying and adapting the VDOGRAB +// library by Shu-Kai Yang. We owe him a great deal of thanks +// for figuring all this out. +// +// http://shukaiyang.myweb.hinet.net/index.html +// +// The license for VDOGRAB is as follows: +// +// "The library is agreed to be used in your production WITHOUT any +// fee. And the binary file vdograb.dll is agreed to be distributed +// WITHOUT any fee. Any production using the library DOES NOT need to +// mark the library on its logo. Therefore, I, the author or the +// library, AM NOT responsible to any problems possibly caused by the +// library in your production. I have NO DUTY to fixing any damage or +// providing any support." +// +//////////////////////////////////////////////////////////////////// + +#define WIN32_LEAN_AND_MEAN + +#undef Configure + +#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter +#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union +#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated +#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated +#pragma warning(disable:4514) // warning C4514: "unreferenced inline function has been removed" + +#include +#include +#include +#include +#include // Generated IDL header file for streams interfaces +#include // ActiveMovie video interfaces and definitions +#include // ActiveMovie audio interfaces and definitions +#include // generated from control.odl +#include // event code definitions +#include // declaration of type GUIDs and well-known clsids +#include // HRESULT status and error definitions +#include // External device control interface defines +#include // audio filter device error event codes +#include // DVD error event codes + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////// +// +// I'm hiding the entire definition of class WebcamVideoCursor in +// the OS specific portion of the WebcamVideo CXX file. This goes +// against Panda3D coding conventions: normally, classes get +// exposed in header files. However, this class is such a mess +// of OS-specific code and conditional compilation that it's better +// to just hide it entirely. - Josh +// +//////////////////////////////////////////////////////////////////// + +class WebcamVideoCursor: public MovieVideoCursor +{ +public: + WebcamVideoCursor(WebcamVideo *src); + virtual ~WebcamVideoCursor(); + virtual void fetch_into_buffer(double time, unsigned char *block, bool rgba); + +public: + void cleanup(); + + class CSampleGrabberCB : public ISampleGrabberCB + { + public: + int width; + int height; + + ULONG __stdcall AddRef() { return 2; } + ULONG __stdcall Release() { return 1; } + + HRESULT __stdcall QueryInterface(REFIID riid, void ** ppv); + HRESULT __stdcall SampleCB(double SampleTime, IMediaSample *pSample); + HRESULT __stdcall BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize); + }; + + IGraphBuilder *_pGraphBuilder; + ICaptureGraphBuilder2 *_pCaptureBuilder; + IBaseFilter *_pSrcFilter; + CComPtr _pSampleGrabber; + IBaseFilter *_pVMR9; + IMediaControl *_pMediaCtrl; + IVMRWindowlessControl *_pWindowssCtrl; + CSampleGrabberCB _sample_grabber_cb; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + MovieVideoCursor::init_type(); + register_type(_type_handle, "WebcamVideoCursor", + MovieVideoCursor::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +TypeHandle WebcamVideoCursor::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::get_num_devices +// Access: Static, Published +// Description: +//////////////////////////////////////////////////////////////////// +int WebcamVideo:: +get_num_devices() { + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::get_device_name +// Access: Static, Published +// Description: +//////////////////////////////////////////////////////////////////// +string WebcamVideo:: +get_device_name(int n) { + return ""; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::open +// Access: Published, Virtual +// Description: Open this video, returning a MovieVideoCursor. +//////////////////////////////////////////////////////////////////// +PT(MovieVideoCursor) WebcamVideo:: +open() { + return new WebcamVideoCursor(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::init_cursor_type +// Access: Static, Public +// Description: Calls WebcamVideoCursor::init_type +//////////////////////////////////////////////////////////////////// +void WebcamVideo:: +init_cursor_type() { + WebcamVideoCursor::init_type(); + CoInitialize(NULL); +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideoCursor:: +WebcamVideoCursor(WebcamVideo *src) : + MovieVideoCursor(src), + _pGraphBuilder(NULL), + _pCaptureBuilder(NULL), + _pSrcFilter(NULL), + _pVMR9(NULL), + _pMediaCtrl(NULL), + _pWindowssCtrl(NULL) +{ + + wchar_t *pFriendlyName = 0; // Put the device name here. + + AM_MEDIA_TYPE mediaType; + VIDEOINFOHEADER *pVideoInfo; + RECT srcRect, destRect; + + ICreateDevEnum *pCreateDevEnum=NULL; + IEnumMoniker *pEnumMoniker=NULL; + IPropertyBag *property=NULL; + IMoniker *pMoniker=NULL; + IVMRFilterConfig *pFilterConfig; + + HRESULT hResult; + ULONG cFetched; + VARIANT name; + + static wchar_t deviceName[256]; + + hResult=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, + IID_IGraphBuilder,(void**)&_pGraphBuilder); + if(hResult != S_OK) { cleanup(); return; } + + + hResult=CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, + IID_ICaptureGraphBuilder2, (void**)&_pCaptureBuilder); + if(hResult != S_OK) { cleanup(); return; } + + _pCaptureBuilder->SetFiltergraph(_pGraphBuilder); + cerr << " IID_IGraphBuilder & IID_ICaptureGraphBuilder2 are established.\n"; + + hResult=_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&_pMediaCtrl); + if(FAILED(hResult)) + { cerr << " Can not get the IID_IMediaControl interface!"; + cleanup(); return; } + cerr << " IID_IMediaControl interface is acquired.\n"; + + + + + + hResult=CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + IID_ICreateDevEnum, (void**)&pCreateDevEnum); + if(hResult != S_OK) { cleanup(); return; } + cerr << " IID_ICreateDevEnum of CLSID_SystemDeviceEnum is acquired.\n"; + + + hResult=pCreateDevEnum->CreateClassEnumerator + (CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); + if(hResult != DD_OK) + { cleanup(); pCreateDevEnum->Release(); return; } + cerr << " Moniker of CLSID_VideoInputDeviceCategory is acquired.\n"; + + + while(pEnumMoniker->Next(1, &pMoniker, &cFetched) == S_OK) + { if(pFriendlyName) + { + pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&property); + VariantInit(&name); + hResult=property->Read(L"FriendlyName", &name, 0); + wcscpy(deviceName, name.bstrVal); + VariantClear(&name); + property->Release(); + cerr << " Enumerated device: " << deviceName << "\n"; + + if(wcscmp(deviceName, pFriendlyName) == 0) + { pMoniker->BindToObject + (NULL, NULL, IID_IBaseFilter, (void**)&_pSrcFilter); } + } + else + { + pMoniker->BindToObject + (NULL, NULL, IID_IBaseFilter, (void**)&_pSrcFilter); + } + + pMoniker->Release(); + if(_pSrcFilter != NULL) { break; } + } + + + pCreateDevEnum->Release(); + pEnumMoniker->Release(); + + if(_pSrcFilter == NULL) + { cerr << " Such capture device is not found.\n"; + cleanup(); return; } + cerr << " The capture filter is acquired.\n"; + + + hResult=_pGraphBuilder->AddFilter(_pSrcFilter, L"Capture Filter"); + if(hResult != DD_OK) + { cerr << " The capture filter can not be added to the graph.\n"; + cleanup(); return; } + cerr << " The capture filter has been added to the graph.\n"; + + + _pSampleGrabber.CoCreateInstance(CLSID_SampleGrabber); + if(!_pSampleGrabber) + { cerr << " Can not create the sample grabber, maybe qedit.dll is not registered?"; + cleanup(); return; } + + + CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberFilter(_pSampleGrabber); + cerr << " IID_IBaseFilter of CLSID_SampleGrabber is acquired.\n"; + + + ZeroMemory(&mediaType, sizeof(AM_MEDIA_TYPE)); + mediaType.majortype=MEDIATYPE_Video; + mediaType.subtype=MEDIASUBTYPE_RGB24; + hResult=_pSampleGrabber->SetMediaType(&mediaType); + if(FAILED(hResult)) + { cerr << " Fail to set the media type!"; + cleanup(); return; } + cerr << " The media type of the sample grabber is set 24-bit RGB.\n"; + + + hResult=_pGraphBuilder->AddFilter(pGrabberFilter, L"Sample Grabber"); + if(FAILED(hResult)) + { cerr << " Fail to add the sample grabber to the graph."; + cleanup(); return; } + cerr << " The sample grabber has been added to the graph.\n"; + + hResult=CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC, + IID_IBaseFilter, (void**)&_pVMR9); + if(FAILED(hResult)) + { cerr << " Can not create the video mixing renderer."; + cleanup(); return; } + cerr << " IID_IBaseFilter of CLSID_VideoMixingRenderer is acquired.\n"; + + + hResult=_pGraphBuilder->AddFilter(_pVMR9, L"Video Mixing Renderer"); + if(FAILED(hResult)) + { cerr << " Fail to add the VMR to the graph."; + cleanup(); return; } + cerr << " The VMR has been added to the graph.\n"; + + + hResult=_pVMR9->QueryInterface(IID_IVMRFilterConfig, (void**)&pFilterConfig); + if(FAILED(hResult)) + { cerr << " Can not get IVMRFilterConfig interface of VMR."; + cleanup(); return; } + + hResult=pFilterConfig->SetRenderingMode(VMRMode_Windowless); + pFilterConfig->Release(); + + if(FAILED(hResult)) + { cerr << " Can not set VMR in windowless mode."; + cleanup(); return; } + cerr << " VMR is set in windowless mode by IVMRFilterConfig interface.\n"; + + hResult=_pVMR9->QueryInterface(IID_IVMRWindowlessControl, (void**)&_pWindowssCtrl); + if(FAILED(hResult)) + { cerr << " Can not get the IVMRWindowlessControl interface."; + cleanup(); return; } + + cerr << " IID_IVMRWindowlessControl interface is acquired.\n"; + _pWindowssCtrl->SetVideoClippingWindow(GetDesktopWindow()); + + + + + + hResult=_pCaptureBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, + &MEDIATYPE_Video, _pSrcFilter, pGrabberFilter, _pVMR9); + if(FAILED(hResult)) + { hResult=_pCaptureBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, _pSrcFilter, pGrabberFilter, _pVMR9); + + if(FAILED(hResult)) + { cerr << " ICaptureGraphBuilder2::RenderStream() can not connect the pins.\n"; + cleanup(); return; } + } + + + + + hResult=_pSampleGrabber->GetConnectedMediaType(&mediaType); + if(FAILED(hResult)) + { cerr << " Failed to read the connected media type."; + cleanup(); return; } + + + pVideoInfo=(VIDEOINFOHEADER*)mediaType.pbFormat; + _sample_grabber_cb.width=pVideoInfo->bmiHeader.biWidth; + _sample_grabber_cb.height=pVideoInfo->bmiHeader.biHeight; + + + if(mediaType.cbFormat != 0) + { CoTaskMemFree((PVOID)mediaType.pbFormat); + mediaType.cbFormat=0; + mediaType.pbFormat=NULL; } + + if(mediaType.pUnk != NULL) + { mediaType.pUnk->Release(); + mediaType.pUnk=NULL; } + + + _pSampleGrabber->SetBufferSamples(FALSE); + _pSampleGrabber->SetOneShot(FALSE); + hResult=_pSampleGrabber->SetCallback(&_sample_grabber_cb, 1); + if(FAILED(hResult)) + { cerr << " Can not set the callback interface!"; + cleanup(); return; } + + + SetRect(&srcRect, 0, 0, _sample_grabber_cb.width, _sample_grabber_cb.height); + SetRect(&destRect, 0, 0, _sample_grabber_cb.width, _sample_grabber_cb.height); + _pWindowssCtrl->SetVideoPosition(&srcRect, &destRect); + + if(_pMediaCtrl) { + _pMediaCtrl->Run(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::cleanup +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void WebcamVideoCursor:: +cleanup() { + if (_pMediaCtrl) { + _pMediaCtrl->Stop(); + } + + if(_pWindowssCtrl) { _pWindowssCtrl->Release(); _pWindowssCtrl=NULL; } + if(_pMediaCtrl) { _pMediaCtrl->Release(); _pMediaCtrl=NULL; } + if(_pCaptureBuilder) { _pCaptureBuilder->Release(); _pCaptureBuilder=NULL; } + if(_pGraphBuilder) { _pGraphBuilder->Release(); _pGraphBuilder=NULL; } + if(_pSampleGrabber.p) { _pSampleGrabber.Release(); } + if(_pVMR9) { _pVMR9->Release(); _pVMR9=NULL; } + if(_pSrcFilter) { _pSrcFilter->Release(); _pSrcFilter=NULL; } +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +WebcamVideoCursor:: +~WebcamVideoCursor() { + cleanup(); +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::fetch_into_buffer +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void WebcamVideoCursor:: +fetch_into_buffer(double time, unsigned char *block, bool rgba) { + MovieVideoCursor::fetch_into_buffer(time, block, rgba); +} + + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::CSampleGrabberCB::QueryInterface +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +HRESULT __stdcall WebcamVideoCursor::CSampleGrabberCB::QueryInterface(REFIID riid, void **ppv) +{ + if((riid == IID_ISampleGrabberCB) || (riid == IID_IUnknown)) { + *ppv=(void *)static_cast (this); + return NOERROR; + } + + return E_NOINTERFACE; +} + + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::CSampleGrabberCB::SampleCB +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +HRESULT __stdcall WebcamVideoCursor::CSampleGrabberCB::SampleCB(double SampleTime, IMediaSample *pSample) +{ + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideoCursor::CSampleGrabberCB::BufferCB +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +HRESULT __stdcall WebcamVideoCursor::CSampleGrabberCB::BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize) +{ + // Store the data! + return 0; +} + diff --git a/panda/src/movies/webcamVideoNull.cxx b/panda/src/movies/webcamVideoNull.cxx new file mode 100644 index 0000000000..5befb6379b --- /dev/null +++ b/panda/src/movies/webcamVideoNull.cxx @@ -0,0 +1,57 @@ +// Filename: webcamVideoNull.cxx +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2007, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::get_num_devices +// Access: Static, Published +// Description: +//////////////////////////////////////////////////////////////////// +int WebcamVideo:: +get_num_devices() { + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::get_device_name +// Access: Static, Published +// Description: +//////////////////////////////////////////////////////////////////// +string WebcamVideo:: +get_device_name(int n) { + return ""; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::open +// Access: Published, Virtual +// Description: Open this video, returning a MovieVideoCursor. +//////////////////////////////////////////////////////////////////// +PT(MovieVideoCursor) WebcamVideo:: +open() { + skel_cat.error() << "WebcamVideo support is not compiled in.\n"; + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: WebcamVideo::init_cursor_type +// Access: Static, Public +// Description: Calls WebcamVideoCursor::init_type +//////////////////////////////////////////////////////////////////// +void WebcamVideo:: +init_cursor_type() { +} diff --git a/panda/src/movies/webcamVideoV4L.cxx b/panda/src/movies/webcamVideoV4L.cxx new file mode 100644 index 0000000000..af35266a5a --- /dev/null +++ b/panda/src/movies/webcamVideoV4L.cxx @@ -0,0 +1,21 @@ +// Filename: webcamVideoV4L.cxx +// Created by: jyelon (01Nov2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +// Video4Linux version not implemented yet. + +#include "webcamVideoNull.cxx"