diff --git a/lib/native/windows-64/jndirectshow.dll b/lib/native/windows-64/jndirectshow.dll index 56909b7e8d1fda887fcd3288f60657cf6e8aaeee..06e7a87b0f5e032b010c5ecfafa7c18e87f22e25 100644 Binary files a/lib/native/windows-64/jndirectshow.dll and b/lib/native/windows-64/jndirectshow.dll differ diff --git a/lib/native/windows/jndirectshow.dll b/lib/native/windows/jndirectshow.dll index e1ed7a899a6d1432a1a443a401762725442913e9..3326eec6925c12f6feb090d8b69682b4c8f543a3 100644 Binary files a/lib/native/windows/jndirectshow.dll and b/lib/native/windows/jndirectshow.dll differ diff --git a/src/native/windows/directshow/DSCaptureDevice.cpp b/src/native/windows/directshow/DSCaptureDevice.cpp index 94d5476343d9daef3f07a3db6e4fa63d3e0c9089..2ee47577bf9e38cd89ec81ca1008ee7f33ea8911 100644 --- a/src/native/windows/directshow/DSCaptureDevice.cpp +++ b/src/native/windows/directshow/DSCaptureDevice.cpp @@ -9,6 +9,7 @@ * \file DSCaptureDevice.cpp * \brief DirectShow capture device. * \author Sebastien Vincent + * \author Lyubomir Marinov * \date 2010 */ @@ -17,15 +18,6 @@ DEFINE_GUID(CLSID_SampleGrabber, 0xc1f400a0, 0x3f08, 0x11d3, 0x9f, 0x0b, 0x00, 0x60, 0x08, 0x03, 0x9e, 0x37); DEFINE_GUID(CLSID_NullRenderer, 0xc1f400a4, 0x3f08, 0x11d3, 0x9f, 0x0b, 0x00, 0x60, 0x08, 0x03, 0x9e, 0x37); -/* implementation of ISampleGrabber */ -DSGrabberCallback::DSGrabberCallback() -{ -} - -DSGrabberCallback::~DSGrabberCallback() -{ -} - STDMETHODIMP DSGrabberCallback::SampleCB(double time, IMediaSample* sample) { BYTE* data = NULL; @@ -74,9 +66,7 @@ STDMETHODIMP_(ULONG) DSGrabberCallback::Release() DSCaptureDevice::DSCaptureDevice(const WCHAR* name) { if(name) - { m_name = wcsdup(name); - } m_flip = false; m_callback = NULL; @@ -97,56 +87,36 @@ DSCaptureDevice::~DSCaptureDevice() { /* remove all added filters from filter graph */ if(m_srcFilter) - { m_filterGraph->RemoveFilter(m_srcFilter); - } if(m_renderer) - { m_filterGraph->RemoveFilter(m_renderer); - } if(m_sampleGrabberFilter) - { m_filterGraph->RemoveFilter(m_sampleGrabberFilter); - } } /* clean up COM stuff */ if(m_renderer) - { m_renderer->Release(); - } if(m_sampleGrabber) - { m_sampleGrabber->Release(); - } if(m_sampleGrabberFilter) - { m_sampleGrabberFilter->Release(); - } if(m_srcFilter) - { m_srcFilter->Release(); - } if(m_captureGraphBuilder) - { m_captureGraphBuilder->Release(); - } if(m_filterGraph) - { m_filterGraph->Release(); - } if(m_name) - { free(m_name); - } } const WCHAR* DSCaptureDevice::getName() const @@ -154,15 +124,12 @@ const WCHAR* DSCaptureDevice::getName() const return m_name; } -bool DSCaptureDevice::setFormat(const VideoFormat& format) +bool DSCaptureDevice::setFormat(const DSFormat& format) { HRESULT ret; IAMStreamConfig* streamConfig = NULL; AM_MEDIA_TYPE* mediaType = NULL; - /* force to stop */ - stop(); - /* get the right interface to change capture settings */ ret = m_captureGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_srcFilter, IID_IAMStreamConfig, (void**)&streamConfig); @@ -253,33 +220,24 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker) HRESULT ret = 0; if(!m_name || !moniker) - { return false; - } if(m_filterGraph) - { - /* already initialized */ - return false; - } + return false; /* This instance has already been initialized. */ /* create the filter and capture graph */ ret = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph2, (void**)&m_filterGraph); if(FAILED(ret)) - { return false; - } ret = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&m_captureGraphBuilder); if(FAILED(ret)) - { return false; - } m_captureGraphBuilder->SetFiltergraph(m_filterGraph); @@ -287,40 +245,30 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker) ret = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&m_graphController); if(FAILED(ret)) - { return false; - } /* add source filter to the filter graph */ ret = moniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&m_srcFilter); if(ret != S_OK) - { return false; - } WCHAR* name = wcsdup(m_name); ret = m_filterGraph->AddFilter(m_srcFilter, name); free(name); if(ret != S_OK) - { return false; - } ret = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_sampleGrabberFilter); if(ret != S_OK) - { return false; - } /* get sample grabber */ ret = m_sampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_sampleGrabber); if(ret != S_OK) - { return false; - } /* and sample grabber to the filter graph */ ret = m_filterGraph->AddFilter(m_sampleGrabberFilter, L"SampleGrabberFilter"); @@ -336,18 +284,14 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker) /* set the callback handler */ if(ret != S_OK) - { return false; - } /* set renderer */ ret = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_renderer); if(ret != S_OK) - { return false; - } /* add renderer to the filter graph */ m_filterGraph->AddFilter(m_renderer, L"NullRenderer"); @@ -384,9 +328,7 @@ bool DSCaptureDevice::initDevice(IMoniker* moniker) } if((caps & VideoControlFlag_FlipHorizontal) != 0) - { caps = caps & ~(VideoControlFlag_FlipHorizontal); - } videoControl->SetMode(pin, caps); } @@ -422,7 +364,7 @@ void DSCaptureDevice::initSupportedFormats() { if(streamConfig->GetStreamCaps(i, &mediaType, allocBytes) == S_OK) { - struct VideoFormat format; + struct DSFormat format; VIDEOINFOHEADER* hdr = (VIDEOINFOHEADER*)mediaType->pbFormat; if(hdr) @@ -441,74 +383,50 @@ void DSCaptureDevice::initSupportedFormats() } } -std::list<VideoFormat> DSCaptureDevice::getSupportedFormats() const +std::list<DSFormat> DSCaptureDevice::getSupportedFormats() const { return m_formats; } bool DSCaptureDevice::buildGraph() { - REFERENCE_TIME start = 0; - REFERENCE_TIME stop = MAXLONGLONG; - HRESULT ret = 0; - -#ifndef RENDERER_DEBUG - ret = m_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, - m_srcFilter, m_sampleGrabberFilter, - m_renderer); -#else - ret = m_captureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, - m_srcFilter, m_sampleGrabberFilter, - NULL); -#endif - - if(FAILED(ret)) + HRESULT hr + = m_captureGraphBuilder->RenderStream( + &PIN_CATEGORY_PREVIEW, + &MEDIATYPE_Video, + m_srcFilter, + m_sampleGrabberFilter, + m_renderer); + + if (SUCCEEDED(hr)) { - /* fprintf(stderr, "problem render stream\n"); */ - return false; + REFERENCE_TIME start = 0; + REFERENCE_TIME stop = MAXLONGLONG; + + hr + = m_captureGraphBuilder->ControlStream( + &PIN_CATEGORY_PREVIEW, + &MEDIATYPE_Video, + m_srcFilter, + &start, &stop, + 1, 2); + return SUCCEEDED(hr); } - - /* start capture */ - ret = m_captureGraphBuilder->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, - m_srcFilter, &start, &stop, 1, 2); - - /* we need this to finalize graph (maybe other filter will be added) */ - //m_graphController->Run(); - //this->stop(); - - return !FAILED(ret); + else + return false; } bool DSCaptureDevice::start() { - if(!m_renderer || !m_sampleGrabberFilter || !m_srcFilter || !m_graphController) - { - return false; - } - - m_graphController->Run(); - m_renderer->Run(0); - m_sampleGrabberFilter->Run(0); - m_srcFilter->Run(0); - return true; + return m_graphController ? SUCCEEDED(m_graphController->Run()) : false; } bool DSCaptureDevice::stop() { - if(!m_renderer || !m_sampleGrabberFilter || !m_srcFilter || !m_graphController) - { - return false; - } - - m_srcFilter->Stop(); - m_sampleGrabberFilter->Stop(); - m_renderer->Stop(); - m_graphController->Stop(); - - return true; + return m_graphController ? SUCCEEDED(m_graphController->Stop()) : false; } -VideoFormat DSCaptureDevice::getFormat() const +DSFormat DSCaptureDevice::getFormat() const { return m_format; } diff --git a/src/native/windows/directshow/DSCaptureDevice.h b/src/native/windows/directshow/DSCaptureDevice.h index cda7ad01bc8b30c45e8abf403752d024e3683778..6af3ecbe6af0feeaadcd5640933093cbc8d92e99 100644 --- a/src/native/windows/directshow/DSCaptureDevice.h +++ b/src/native/windows/directshow/DSCaptureDevice.h @@ -12,8 +12,8 @@ * \date 2010 */ -#ifndef DS_CAPTURE_DEVICE_H -#define DS_CAPTURE_DEVICE_H +#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_ +#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_ #include <list> @@ -22,7 +22,7 @@ #include <dshow.h> #include <qedit.h> -#include "VideoFormat.h" +#include "DSFormat.h" /** * \class DSGrabberCallback @@ -34,12 +34,12 @@ public: /** * \brief Constructor. */ - DSGrabberCallback(); + DSGrabberCallback() {}; /** * \brief Destructor. */ - virtual ~DSGrabberCallback(); + virtual ~DSGrabberCallback() {}; /** * \brief Method callback when device capture a frame. @@ -120,13 +120,13 @@ public: * \return true if change is successful, false otherwise (format unsupported, ...) * \note This method stop stream so you have to call start() after. */ - bool setFormat(const VideoFormat& format); + bool setFormat(const DSFormat& format); /** * \brief Get list of supported formats. * \return list of supported formats. */ - std::list<VideoFormat> getSupportedFormats() const; + std::list<DSFormat> getSupportedFormats() const; /** * \brief Build the filter graph for this capture device. @@ -163,7 +163,7 @@ public: * \brief Get current format. * \return current format */ - VideoFormat getFormat() const; + DSFormat getFormat() const; /** * \brief Get current bit per pixel. @@ -194,9 +194,9 @@ private: DSGrabberCallback* m_callback; /** - * \brief List of VideoFormat. + * \brief List of DSFormat. */ - std::list<VideoFormat> m_formats; + std::list<DSFormat> m_formats; /** * \brief Reference of the filter graph. @@ -236,7 +236,7 @@ private: /** * \brief Current format. */ - VideoFormat m_format; + DSFormat m_format; /** * \brief Current bit per pixel. @@ -249,4 +249,4 @@ private: bool m_flip; }; -#endif /* DS_CAPTURE_DEVICE_H */ +#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSCAPTUREDEVICE_H_ */ diff --git a/src/native/windows/directshow/DSFormat.h b/src/native/windows/directshow/DSFormat.h new file mode 100644 index 0000000000000000000000000000000000000000..cfa9c332f4c6aa792a22a2984f708a2ac1b594ba --- /dev/null +++ b/src/native/windows/directshow/DSFormat.h @@ -0,0 +1,29 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +/** + * \file DSFormat.h + * \brief Useful structures and enumerations for video/DirectShow format. + * \author Sebastien Vincent + */ + +#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_ +#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_ + +/** + * \struct DSFormat + * \brief Information about video/DirectShow format + */ +struct DSFormat +{ + size_t width; /**< Video width */ + size_t height; /**< Video height */ + unsigned long pixelFormat; /**< Pixel format */ + GUID mediaType; /**< Media type */ +}; + +#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSFORMAT_H_ */ diff --git a/src/native/windows/directshow/DSManager.cpp b/src/native/windows/directshow/DSManager.cpp index 1ec6a61ad98b4f7441fab7cd291f27cdccc5a5b4..ad90c639743661d147ae50385b886068fb442953 100644 --- a/src/native/windows/directshow/DSManager.cpp +++ b/src/native/windows/directshow/DSManager.cpp @@ -9,6 +9,7 @@ * \file DSManager.cpp * \brief DirectShow capture devices manager. * \author Sebastien Vincent + * \author Lyubomir Marinov * \date 2010 */ @@ -18,80 +19,37 @@ #include "DSCaptureDevice.h" #include <qedit.h> -/* initialization of static member variables */ -DSManager* DSManager::m_instance = NULL; - -DSManager* DSManager::getInstance() -{ - return m_instance; -} - DSManager::DSManager() { - DWORD ret = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if(ret != S_OK && ret != S_FALSE) - { - //seems to be a problem with COM initialization - /* - printf("problem\n");fflush(stdout); - if(ret == RPC_E_CHANGED_MODE) - { - printf("rpc\n");fflush(stdout); - } - else if(ret == E_INVALIDARG) - { - printf("invalid arg\n");fflush(stdout); - } - else if(ret == E_OUTOFMEMORY) - { - printf("outofmemory\n");fflush(stdout); - } - else if(ret == E_UNEXPECTED) - { - printf("unexpected\n");fflush(stdout); - } - */ - - comInited = false; - return; - } - - comInited = true; - initCaptureDevices(); + HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + + if (SUCCEEDED(hr)) + initCaptureDevices(); + + /* + * Each successful call to CoInitializeEx must be balanced by a + * corresponding call to CoUninitialize in order to close the COM library + * gracefully on a thread. Unfortunately, the multithreaded architectures of + * FMJ and libjitsi do not really guarantee that the destructor of this + * DSManager will be invoked on the same thread on which the constructor of + * this DSManager has been invoked in the first place. + */ + _coUninitialize = false; } DSManager::~DSManager() { for(std::list<DSCaptureDevice*>::iterator it = m_devices.begin() ; it != m_devices.end() ; ++it) - { delete *it; - } m_devices.clear(); - /* one CoUninitialize per CoInitialize */ - if(comInited) - { - CoUninitialize(); - } -} - -bool DSManager::initialize() -{ - if(!m_instance) - { - m_instance = new DSManager(); - } - - return m_instance != NULL; -} - -void DSManager::destroy() -{ - if(m_instance) - { - delete m_instance; - m_instance = NULL; - } + /* + * Each successful call to CoInitializeEx must be balanced by a + * corresponding call to CoUninitialize in order to close the COM library + * gracefully on a thread. + */ + if (_coUninitialize) + ::CoUninitialize(); } std::list<DSCaptureDevice*> DSManager::getDevices() const @@ -99,11 +57,6 @@ std::list<DSCaptureDevice*> DSManager::getDevices() const return m_devices; } -size_t DSManager::getDevicesCount() -{ - return m_devices.size(); -} - void DSManager::initCaptureDevices() { HRESULT ret = 0; @@ -116,9 +69,7 @@ void DSManager::initCaptureDevices() { /* clean up our list in case of reinitialization */ for(std::list<DSCaptureDevice*>::iterator it = m_devices.begin() ; it != m_devices.end() ; ++it) - { delete *it; - } m_devices.clear(); } @@ -127,9 +78,7 @@ void DSManager::initCaptureDevices() IID_ICreateDevEnum, (void**)&devEnum); if(FAILED(ret)) - { return; - } ret = devEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &monikerEnum, 0); diff --git a/src/native/windows/directshow/DSManager.h b/src/native/windows/directshow/DSManager.h index e68719d8e3d74aacd2d8a3e15ede88b85436218c..5d49c07e54e02e25f50e43287680948a2b80fa9b 100644 --- a/src/native/windows/directshow/DSManager.h +++ b/src/native/windows/directshow/DSManager.h @@ -9,11 +9,12 @@ * \file DSManager.h * \brief DirectShow capture devices manager. * \author Sebastien Vincent + * \author Lyubomir Marinov * \date 2010 */ -#ifndef DS_MANAGER_H -#define DS_MANAGER_H +#ifndef _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_ +#define _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_ #include <list> @@ -29,36 +30,14 @@ class DSManager { public: /** - * \brief Destructor. - */ - ~DSManager(); - - /** - * \brief Initialize DirectShow manager. - * - * Call this method to initialize DirectShow capture devices. - * It can also be used to reinitialize and update list of current - * devices but be sure to not use any of previous DSCaptureDevice after. - * - * \return true if initialize succeed, false otherwise - * \note You MUST call before any use of DirectShow. - */ - static bool initialize(); - - /** - * \brief Destroy DirectShow manager. - * \note You MUST call this method when you have finished - * using DirectShow. + * \brief Constructor. */ - static void destroy(); + DSManager(); /** - * \brief Get unique instance. - * \return DirectShow manager instance - * \note You MUST call DSManager::initialize before - * any use of this method or you will get NULL as return value. + * \brief Destructor. */ - static DSManager* getInstance(); + ~DSManager(); /** * \brief Get all available capture video devices. @@ -66,23 +45,7 @@ public: */ std::list<DSCaptureDevice*> getDevices() const; - /** - * \brief Get number of devices. - * \return number of available devices - */ - size_t getDevicesCount(); - private: - /** - * \brief Unique instance of DirectShow manager. - */ - static DSManager* m_instance; - - /** - * \brief Constructor. - */ - DSManager(); - /** * \brief Get and initialize video capture devices. */ @@ -93,15 +56,10 @@ private: */ std::list<DSCaptureDevice*> m_devices; - /** - * \brief Easy use of template-based list iterator. - */ - typedef std::list<DSCaptureDevice*>::iterator DeviceListIterator; - /** * If COM backend is initialized. */ - bool comInited; + bool _coUninitialize; }; -#endif /* DS_MANAGER_H */ +#endif /* _ORG_JITSI_IMPL_NEOMEDIA_JMFEXT_MEDIA_PROTOCOL_DIRECTSHOW_DSMANAGER_H_ */ diff --git a/src/native/windows/directshow/VideoFormat.h b/src/native/windows/directshow/VideoFormat.h deleted file mode 100644 index 39fc7c5d5cfc1b3fac15ae08955d6694e857e3f3..0000000000000000000000000000000000000000 --- a/src/native/windows/directshow/VideoFormat.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -/** - * \file VideoFormat.h - * \brief Useful structures and enumerations for video format. - * \author Sebastien Vincent - */ - -#ifndef VIDEO_FORMAT_H -#define VIDEO_FORMAT_H - -/** - * \struct VideoFormat - * \brief Information about video format - */ -struct VideoFormat -{ - size_t width; /**< Video width */ - size_t height; /**< Video height */ - unsigned long pixelFormat; /**< Pixel format */ - GUID mediaType; /**< Media type */ -}; - -#endif /* VIDEO_FORMAT_H */ diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h deleted file mode 100644 index fd30b11fa6e428706bc76ca70f9396b1926c333f..0000000000000000000000000000000000000000 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class org_jitsi_impl_neomedia_directshow_DSCaptureDevice */ - -#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSCaptureDevice -#define _Included_org_jitsi_impl_neomedia_directshow_DSCaptureDevice -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: getBytes - * Signature: (JJI)I - */ -JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getBytes - (JNIEnv *, jclass, jlong, jlong, jint); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: close - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_close - (JNIEnv *, jobject, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: getFormat - * Signature: (J)Lorg/jitsi/impl/neomedia/directshow/DSFormat; - */ -JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getFormat - (JNIEnv *, jobject, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: getName - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getName - (JNIEnv *, jobject, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: getSupportedFormats - * Signature: (J)[Lorg/jitsi/impl/neomedia/directshow/DSFormat; - */ -JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getSupportedFormats - (JNIEnv *, jobject, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: open - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_open - (JNIEnv *, jobject, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: setDelegate - * Signature: (JLorg/jitsi/impl/neomedia/directshow/DSCaptureDevice/GrabberDelegate;)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setDelegate - (JNIEnv *, jobject, jlong, jobject); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSCaptureDevice - * Method: setFormat - * Signature: (JLorg/jitsi/impl/neomedia/directshow/DSFormat;)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setFormat - (JNIEnv *, jobject, jlong, jobject); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp deleted file mode 100644 index 01fc0d687c2969ef4ae857f30b74375b11f6d776..0000000000000000000000000000000000000000 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ - -#include "org_jitsi_impl_neomedia_directshow_DSFormat.h" - -#include <windows.h> -#include <dshow.h> -#include <uuids.h> - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB24PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_RGB24.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB32PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_RGB32.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getARGBPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_ARGB32.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getAYUVPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_AYUV.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYUY2PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_YUY2.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getUYVYPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_UYVY.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC1PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IMC1.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC2PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IMC2.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC3PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IMC3.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC4PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IMC4.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYV12PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_YV12.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getNV12PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_NV12.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIF09PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IF09.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIYUVPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_IYUV.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY211PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_Y211.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY411PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_Y411.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY41PPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_Y41P.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVU9PixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_YVU9.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVYUPixelFormat - (JNIEnv *, jclass) -{ - return MEDIASUBTYPE_YVYU.Data1; -} - -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getI420PixelFormat - (JNIEnv *, jclass) -{ - return 0x30323449; //MEDIASUBTYPE_I420.Data1; -} diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h deleted file mode 100644 index 4ad0c5e3918b6ef91d2212131aafcea43cfb3c20..0000000000000000000000000000000000000000 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h +++ /dev/null @@ -1,173 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class org_jitsi_impl_neomedia_directshow_DSFormat */ - -#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSFormat -#define _Included_org_jitsi_impl_neomedia_directshow_DSFormat -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getARGBPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getARGBPixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getAYUVPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getAYUVPixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getI420PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getI420PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIF09PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIF09PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIMC1PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC1PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIMC2PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC2PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIMC3PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC3PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIMC4PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIMC4PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getIYUVPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getIYUVPixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getNV12PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getNV12PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getRGB24PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB24PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getRGB32PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getRGB32PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getUYVYPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getUYVYPixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getY211PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY211PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getY411PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY411PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getY41PPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getY41PPixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getYUY2PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYUY2PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getYV12PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYV12PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getYVU9PixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVU9PixelFormat - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSFormat - * Method: getYVYUPixelFormat - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSFormat_getYVYUPixelFormat - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h deleted file mode 100644 index f045e21bb61aabadd9d3bbc92e30b6863b61e957..0000000000000000000000000000000000000000 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h +++ /dev/null @@ -1,37 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class org_jitsi_impl_neomedia_directshow_DSManager */ - -#ifndef _Included_org_jitsi_impl_neomedia_directshow_DSManager -#define _Included_org_jitsi_impl_neomedia_directshow_DSManager -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_jitsi_impl_neomedia_directshow_DSManager - * Method: destroy - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy - (JNIEnv *, jclass, jlong); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSManager - * Method: init - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init - (JNIEnv *, jclass); - -/* - * Class: org_jitsi_impl_neomedia_directshow_DSManager - * Method: getCaptureDevices - * Signature: (J)[J - */ -JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_getCaptureDevices - (JNIEnv *, jobject, jlong); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp similarity index 77% rename from src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp rename to src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp index 45f87dd34cc04f23c55a7519aad7fd2d2d80f8f8..6f7926bf2203e4a90558d96d020dfa41123c4d2b 100644 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp @@ -6,19 +6,20 @@ */ /** - * \file org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp + * \file org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp * \brief JNI part of DSCaptureDevice. * \author Sebastien Vincent + * \author Lyubomir Marinov */ #include "DSCaptureDevice.h" -#include "VideoFormat.h" +#include "DSFormat.h" #ifdef __cplusplus -extern "C" { /* } */ +extern "C" { #endif -#include "org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h" +#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h" /** * \class Grabber. @@ -51,9 +52,7 @@ public: m_dev = NULL; if(m_bytes != NULL) - { delete[] m_bytes; - } } /** @@ -68,9 +67,7 @@ public: JNIEnv* env = NULL; if(m_vm->AttachCurrentThreadAsDaemon((void**)&env, NULL) != 0) - { return E_FAIL; - } delegateClass = env->GetObjectClass(m_delegate); if(delegateClass) @@ -87,7 +84,7 @@ public: size_t width = 0; size_t height = 0; size_t bytesPerPixel = 0; - VideoFormat format = m_dev->getFormat(); + DSFormat format = m_dev->getFormat(); /* get width and height */ width = format.width; height = format.height; @@ -103,16 +100,12 @@ public: length = sample->GetActualDataLength(); if(length == 0) - { return S_OK; - } if(!m_bytes || m_bytesLength < length) { if(m_bytes) - { delete[] m_bytes; - } m_bytes = new BYTE[length]; m_bytesLength = length; @@ -167,88 +160,40 @@ public: DSCaptureDevice* m_dev; }; -/** - * \brief Open native capture device. - * \param env JNI environment - * \param obj DSCaptureDevice object - * \param ptr native pointer of DSCaptureDevice - */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_open - (JNIEnv* env, jobject obj, jlong ptr) +JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getBytes + (JNIEnv* env, jclass clazz, jlong ptr, jlong buf, jint len) { - DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - - dev->buildGraph(); - dev->start(); + /* copy data */ + memcpy((void*)buf, (void*)ptr, len); + return len; } /** - * \brief Close native capture device. + * \brief Connects to the specified capture device. * \param env JNI environment * \param obj DSCaptureDevice object - * \param ptr native pointer of DSCaptureDevice + * \param ptr a pointer to a DSCaptureDevice instance to connect to */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_close - (JNIEnv* env, jobject obj, jlong ptr) +JNIEXPORT void JNICALL +Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_connect + (JNIEnv* env, jobject obj, jlong ptr) { - DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - dev->stop(); -} + DSCaptureDevice* thiz = reinterpret_cast<DSCaptureDevice*>(ptr); -/** - * \brief Get name of native capture device. - * \param env JNI environment - * \param obj DSCaptureDevice object - * \param ptr native pointer of DSCaptureDevice - * \return name of the native capture device - */ -JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getName - (JNIEnv* env, jobject obj, jlong ptr) -{ - DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - jstring ret = NULL; - jsize len = static_cast<jsize>(wcslen(dev->getName())); - jchar* name = new jchar[len]; - - /* jchar is two bytes! */ - memcpy((void*)name, (void*)dev->getName(), len * 2); - - ret = env->NewString(name, len); - delete[] name; - - return ret; + thiz->buildGraph(); } /** - * \brief Set format of native capture device. + * \brief Disconnects from the specified capture device. * \param env JNI environment * \param obj DSCaptureDevice object - * \param ptr native pointer of DSCaptureDevice - * \param format DSFormat to set + * \param ptr a pointer to a DSCaptureDevice instance to disconnect from */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setFormat - (JNIEnv* env, jobject obj, jlong ptr, jobject format) +JNIEXPORT void JNICALL +Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_disconnect + (JNIEnv* env, jobject obj, jlong ptr) { - DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - VideoFormat fmt; - jclass clazz = env->GetObjectClass(format); - - if(clazz) - { - jfieldID fieldH = env->GetFieldID(clazz, "height", "I"); - jfieldID fieldW = env->GetFieldID(clazz, "width", "I"); - jfieldID fieldF = env->GetFieldID(clazz, "pixelFormat", "J"); - jlong f = env->GetLongField(format, fieldF); - jint w = env->GetIntField(format, fieldW); - jint h = env->GetIntField(format, fieldH); - - fmt.width = w; - fmt.height = h; - fmt.pixelFormat = (unsigned long)f; - - dev->setFormat(fmt); - dev->start(); - } + /* TODO Auto-generated method stub */ } /** @@ -258,34 +203,54 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_s * \param native pointer * \return current format */ -JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getFormat +JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getFormat (JNIEnv* env, jobject obj, jlong ptr) { DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - VideoFormat fmt = dev->getFormat(); + DSFormat fmt = dev->getFormat(); jclass clazzDSFormat = NULL; jmethodID initDSFormat = NULL; jobject ret = NULL; /* get DSFormat class to instantiate some object */ - clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/directshow/DSFormat"); + clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat"); if(clazzDSFormat == NULL) - { return NULL; - } initDSFormat = env->GetMethodID(clazzDSFormat, "<init>", "(IIJ)V"); if(initDSFormat == NULL) - { return NULL; - } ret = env->NewObject(clazzDSFormat, initDSFormat, static_cast<size_t>(fmt.width), static_cast<size_t>(fmt.height), static_cast<jlong>(fmt.pixelFormat)); return ret; } +/** + * \brief Get name of native capture device. + * \param env JNI environment + * \param obj DSCaptureDevice object + * \param ptr native pointer of DSCaptureDevice + * \return name of the native capture device + */ +JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getName + (JNIEnv* env, jobject obj, jlong ptr) +{ + DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); + jstring ret = NULL; + jsize len = static_cast<jsize>(wcslen(dev->getName())); + jchar* name = new jchar[len]; + + /* jchar is two bytes! */ + memcpy((void*)name, (void*)dev->getName(), len * 2); + + ret = env->NewString(name, len); + delete[] name; + + return ret; +} + /** * \brief Get formats supported by native capture device. * \param env JNI environment @@ -293,36 +258,32 @@ JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevic * \param ptr native pointer of DSCaptureDevice * \return array of DSFormat object */ -JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getSupportedFormats +JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getSupportedFormats (JNIEnv* env, jobject obj, jlong ptr) { jobjectArray ret = NULL; DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); - std::list<VideoFormat> formats; + std::list<DSFormat> formats; jclass clazzDSFormat = NULL; jmethodID initDSFormat = NULL; jsize i = 0; /* get DSFormat class to instantiate some object */ - clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/directshow/DSFormat"); + clazzDSFormat = env->FindClass("org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat"); if(clazzDSFormat == NULL) - { return NULL; - } initDSFormat = env->GetMethodID(clazzDSFormat, "<init>", "(IIJ)V"); if(initDSFormat == NULL) - { return NULL; - } formats = dev->getSupportedFormats(); ret = env->NewObjectArray(static_cast<jsize>(formats.size()), clazzDSFormat, NULL); - for(std::list<VideoFormat>::iterator it = formats.begin() ; it != formats.end() ; ++it) + for(std::list<DSFormat>::iterator it = formats.begin() ; it != formats.end() ; ++it) { - VideoFormat tmp = (*it); + DSFormat tmp = (*it); jobject o = env->NewObject(clazzDSFormat, initDSFormat, static_cast<size_t>(tmp.width), static_cast<size_t>(tmp.height), static_cast<jlong>(tmp.pixelFormat)); @@ -350,7 +311,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCapture * \param ptr native pointer on DSCaptureDevice * \param delegate delegate object */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_setDelegate +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setDelegate (JNIEnv* env, jobject obj, jlong ptr, jobject delegate) { Grabber* grab = NULL; @@ -378,22 +339,60 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_s { jobject tmp_delegate = ((Grabber*)prev)->m_delegate; if(tmp_delegate) - { env->DeleteGlobalRef(tmp_delegate); - } delete prev; } } +/** + * \brief Set format of native capture device. + * \param env JNI environment + * \param obj DSCaptureDevice object + * \param ptr native pointer of DSCaptureDevice + * \param format DSFormat to set + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat + (JNIEnv* env, jobject obj, jlong ptr, jobject format) +{ + DSCaptureDevice* dev = reinterpret_cast<DSCaptureDevice*>(ptr); + DSFormat fmt; + jclass clazz = env->GetObjectClass(format); -JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_directshow_DSCaptureDevice_getBytes - (JNIEnv* env, jclass clazz, jlong ptr, jlong buf, jint len) + if(clazz) + { + jfieldID fieldH = env->GetFieldID(clazz, "height", "I"); + jfieldID fieldW = env->GetFieldID(clazz, "width", "I"); + jfieldID fieldF = env->GetFieldID(clazz, "pixelFormat", "J"); + jlong f = env->GetLongField(format, fieldF); + jint w = env->GetIntField(format, fieldW); + jint h = env->GetIntField(format, fieldH); + + fmt.width = w; + fmt.height = h; + fmt.pixelFormat = (unsigned long)f; + + dev->setFormat(fmt); + } +} + +JNIEXPORT void JNICALL +Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start + (JNIEnv *env, jobject obj, jlong ptr) { - /* copy data */ - memcpy((void*)buf, (void*)ptr, len); - return len; + DSCaptureDevice *thiz = reinterpret_cast<DSCaptureDevice *>(ptr); + + thiz->start(); } -#ifdef __cplusplus +JNIEXPORT void JNICALL +Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop + (JNIEnv *env, jobject obj, jlong ptr) +{ + DSCaptureDevice *thiz = reinterpret_cast<DSCaptureDevice *>(ptr); + + thiz->stop(); } + +#ifdef __cplusplus +} /* extern "C" { */ #endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h new file mode 100644 index 0000000000000000000000000000000000000000..d0a9024847283822562c106f5f5add1a2dba8eed --- /dev/null +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h @@ -0,0 +1,93 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice */ + +#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice +#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: getBytes + * Signature: (JJI)I + */ +JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getBytes + (JNIEnv *, jclass, jlong, jlong, jint); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: connect + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_connect + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: disconnect + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_disconnect + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: getFormat + * Signature: (J)Lorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat; + */ +JNIEXPORT jobject JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getFormat + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: getName + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getName + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: getSupportedFormats + * Signature: (J)[Lorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat; + */ +JNIEXPORT jobjectArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_getSupportedFormats + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: setDelegate + * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice/GrabberDelegate;)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setDelegate + (JNIEnv *, jobject, jlong, jobject); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: setFormat + * Signature: (JLorg/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat;)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_setFormat + (JNIEnv *, jobject, jlong, jobject); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: start + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_start + (JNIEnv *, jobject, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice + * Method: stop + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice_stop + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..613f39455b388b6b66167500bcf7b66dee0ca4e8 --- /dev/null +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp @@ -0,0 +1,132 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h" + +#include <windows.h> +#include <dshow.h> +#include <uuids.h> + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB24PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_RGB24.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB32PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_RGB32.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getARGBPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_ARGB32.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getAYUVPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_AYUV.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYUY2PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_YUY2.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getUYVYPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_UYVY.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC1PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IMC1.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC2PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IMC2.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC3PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IMC3.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC4PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IMC4.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYV12PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_YV12.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getNV12PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_NV12.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIF09PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IF09.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIYUVPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_IYUV.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY211PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_Y211.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY411PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_Y411.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY41PPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_Y41P.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVU9PixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_YVU9.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVYUPixelFormat + (JNIEnv *, jclass) +{ + return MEDIASUBTYPE_YVYU.Data1; +} + +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getI420PixelFormat + (JNIEnv *, jclass) +{ + return 0x30323449; //MEDIASUBTYPE_I420.Data1; +} diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h new file mode 100644 index 0000000000000000000000000000000000000000..a29c5ba06e11576478146a64dddc48e3a85a4eb6 --- /dev/null +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h @@ -0,0 +1,173 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat */ + +#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat +#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getARGBPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getARGBPixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getAYUVPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getAYUVPixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getI420PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getI420PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIF09PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIF09PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIMC1PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC1PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIMC2PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC2PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIMC3PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC3PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIMC4PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIMC4PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getIYUVPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getIYUVPixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getNV12PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getNV12PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getRGB24PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB24PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getRGB32PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getRGB32PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getUYVYPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getUYVYPixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getY211PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY211PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getY411PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY411PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getY41PPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getY41PPixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getYUY2PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYUY2PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getYV12PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYV12PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getYVU9PixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVU9PixelFormat + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat + * Method: getYVYUPixelFormat + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat_getYVYUPixelFormat + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp similarity index 69% rename from src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp rename to src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp index b938b50783958e01aafe66bbc09acfcd1b89c104..ab218aa72ae98b5177bbff1c14aea03e4a49ddb4 100644 --- a/src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.cpp +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp @@ -6,39 +6,33 @@ */ /** - * \file org_jitsi_impl_neomedia_directshow_DSManager.cpp + * \file org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp * \brief JNI part of DSManager. * \author Sebastien Vincent + * \author Lyubomir Marinov */ #include "DSManager.h" #ifdef __cplusplus -extern "C" { /* } */ +extern "C" { #endif -#include "org_jitsi_impl_neomedia_directshow_DSManager.h" +#include "org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h" #include <stdint.h> - /** * \brief Initialize DSManager singleton. * \param env JNI environment * \param clazz DSManager class * \return native pointer on DSManager singleton instance */ -JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init - (JNIEnv* env, jclass clazz) +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_destroy + (JNIEnv* env, jclass clazz, jlong ptr) { - if(DSManager::initialize()) - { - DSManager* manager = DSManager::getInstance(); - return (jlong) (intptr_t) manager; - } - else - { - return 0; - } + DSManager *thiz = reinterpret_cast<DSManager *>(ptr); + + delete thiz; } /** @@ -47,10 +41,10 @@ JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_init * \param clazz DSManager class * \return native pointer on DSManager singleton instance */ -JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy - (JNIEnv* env, jclass clazz, jlong ptr) +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_init + (JNIEnv* env, jclass clazz) { - DSManager::destroy(); + return (jlong) (intptr_t) new DSManager(); } /** @@ -60,7 +54,7 @@ JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_destroy * \param jlong native pointer of DSManager * \return array of native DSCaptureDevice pointers */ -JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_getCaptureDevices +JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_getCaptureDevices (JNIEnv* env, jobject obj, jlong ptr) { jlongArray ret = NULL; @@ -72,9 +66,7 @@ JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_g ret = env->NewLongArray(static_cast<jsize>(devices.size())); if(!ret) - { return NULL; - } for(std::list<DSCaptureDevice*>::iterator it = devices.begin() ; it != devices.end() ; ++it) { @@ -88,5 +80,5 @@ JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_directshow_DSManager_g } #ifdef __cplusplus -} +} /* extern "C" { */ #endif diff --git a/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h new file mode 100644 index 0000000000000000000000000000000000000000..c43419efa2ecdea242d946deacd0a76fef3ebbdc --- /dev/null +++ b/src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager */ + +#ifndef _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager +#define _Included_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager + * Method: destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_destroy + (JNIEnv *, jclass, jlong); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager + * Method: init + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_init + (JNIEnv *, jclass); + +/* + * Class: org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager + * Method: getCaptureDevices + * Signature: (J)[J + */ +JNIEXPORT jlongArray JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager_getCaptureDevices + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java index b85f9f994c639647e023ffea2c1d31f2a9b6253b..efe82c6bfb260b518e2a058e5acc16712b8c2714 100644 --- a/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java +++ b/src/org/jitsi/impl/neomedia/device/DirectShowSystem.java @@ -11,7 +11,6 @@ import org.jitsi.impl.neomedia.*; import org.jitsi.impl.neomedia.codec.*; import org.jitsi.impl.neomedia.codec.video.*; -import org.jitsi.impl.neomedia.directshow.*; import org.jitsi.impl.neomedia.jmfext.media.protocol.directshow.*; import org.jitsi.service.neomedia.*; import org.jitsi.util.*; @@ -20,10 +19,17 @@ * Discovers and registers DirectShow video capture devices with JMF. * * @author Sebastien Vincent + * @author Lyubomir Marinov */ public class DirectShowSystem extends DeviceSystem { + /** + * The protocol of the <tt>MediaLocator</tt>s identifying QuickTime/QTKit + * capture devices. + */ + private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_DIRECTSHOW; + /** * The <tt>Logger</tt> used by the <tt>DirectShowSystem</tt> class and its * instances for logging output. @@ -31,12 +37,6 @@ public class DirectShowSystem private static final Logger logger = Logger.getLogger(DirectShowSystem.class); - /** - * The protocol of the <tt>MediaLocator</tt>s identifying QuickTime/QTKit - * capture devices. - */ - private static final String LOCATOR_PROTOCOL = LOCATOR_PROTOCOL_DIRECTSHOW; - /** * Constructor. Discover and register DirectShow capture devices * with JMF. @@ -53,60 +53,71 @@ public DirectShowSystem() protected void doInitialize() throws Exception { - DSCaptureDevice devices[] = DSManager.getInstance().getCaptureDevices(); - boolean captureDeviceInfoIsAdded = false; + DSManager manager = new DSManager(); - for(int i = 0, count = (devices == null) ? 0 : devices.length; - i < count; - i++) + try { - long pixelFormat = devices[i].getFormat().getPixelFormat(); - int ffmpegPixFmt = (int) DataSource.getFFmpegPixFmt(pixelFormat); - Format format = null; + DSCaptureDevice devices[] = manager.getCaptureDevices(); + boolean captureDeviceInfoIsAdded = false; - if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE) - { - format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat); - } - else + for(int i = 0, count = (devices == null) ? 0 : devices.length; + i < count; + i++) { - logger.warn("No support for this webcam: " + - devices[i].getName() + "(format " + pixelFormat + - " not supported)"); - continue; - } + DSCaptureDevice device = devices[i]; + long pixelFormat = device.getFormat().getPixelFormat(); + int ffmpegPixFmt + = (int) DataSource.getFFmpegPixFmt(pixelFormat); + Format format = null; + String name = device.getName(); - if(logger.isInfoEnabled()) - { - for(DSFormat f : devices[i].getSupportedFormats()) + if(ffmpegPixFmt != FFmpeg.PIX_FMT_NONE) { - if(f.getWidth() != 0 && f.getHeight() != 0) - logger.info( - "Webcam available resolution for " - + devices[i].getName() - + ":" - + f.getWidth() + "x" + f.getHeight()); + format = new AVFrameFormat(ffmpegPixFmt, (int) pixelFormat); + } + else + { + logger.warn( + "No support for this webcam: " + name + "(format " + + pixelFormat + " not supported)"); + continue; } - } - CaptureDeviceInfo device - = new CaptureDeviceInfo( - devices[i].getName(), - new MediaLocator( - LOCATOR_PROTOCOL + ':' + devices[i].getName()), - new Format[] { format }); + if(logger.isInfoEnabled()) + { + for(DSFormat f : device.getSupportedFormats()) + { + if(f.getWidth() != 0 && f.getHeight() != 0) + { + logger.info( + "Webcam available resolution for " + name + + ":" + f.getWidth() + "x" + + f.getHeight()); + } + } + } - if(logger.isInfoEnabled()) - logger.info("Found[" + i + "]: " + device.getName()); + CaptureDeviceInfo cdi + = new CaptureDeviceInfo( + name, + new MediaLocator( + LOCATOR_PROTOCOL + ':' + name), + new Format[] { format }); - CaptureDeviceManager.addDevice(device); - captureDeviceInfoIsAdded = true; - } + if(logger.isInfoEnabled()) + logger.info("Found[" + i + "]: " + cdi.getName()); - if (captureDeviceInfoIsAdded - && !MediaServiceImpl.isJmfRegistryDisableLoad()) - CaptureDeviceManager.commit(); + CaptureDeviceManager.addDevice(cdi); + captureDeviceInfoIsAdded = true; + } - DSManager.dispose(); + if (captureDeviceInfoIsAdded + && !MediaServiceImpl.isJmfRegistryDisableLoad()) + CaptureDeviceManager.commit(); + } + finally + { + manager.dispose(); + } } } diff --git a/src/org/jitsi/impl/neomedia/directshow/DSManager.java b/src/org/jitsi/impl/neomedia/directshow/DSManager.java deleted file mode 100644 index 858ed4c2b1f03dcbc8df243397384c223c66288a..0000000000000000000000000000000000000000 --- a/src/org/jitsi/impl/neomedia/directshow/DSManager.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jitsi.impl.neomedia.directshow; - -/** - * DirectShow capture device manager. - * - * DSManager act as a singleton. When you need it - * call getInstance and don't forget to call dispose() - * when you have finished. - * - * <code> - * DSManager manager = DSManager.getInstance(); - * - * DSCaptureDevice[] devices = manager.getCaptureDevices(); - * - * // do stuff with capture devices - * // ... - * - * DSManager.dispose(); - * - * // do not use any of DSCaptureDevice objects obtained by - * // manager - * </code> - * - * @author Sebastien Vincent - */ -public class DSManager -{ - /** - * Empty array of <tt>DSCaptureDevice</tt>s. Explicitly defined in order to - * avoid unnecessary allocations. - */ - private static DSCaptureDevice[] EMPTY_DEVICES = new DSCaptureDevice[0]; - - /** - * Unique instance of <tt>DSManager</tt>. - */ - private static DSManager instance = null; - - /** - * Reference count. - */ - private static int ref = 0; - - /** - * Synchronization object. - */ - private static Object sync = new Object(); - - static - { - System.loadLibrary("jndirectshow"); - } - - /** - * Delete native pointer. - * - * @param ptr native pointer to delete - */ - private static native void destroy(long ptr); - - /** - * Dispose the object. - */ - public static synchronized void dispose() - { - synchronized(sync) - { - ref--; - - if(ref == 0 && instance != null && instance.ptr != 0) - { - destroy(instance.ptr); - } - instance = null; - ref = 0; - } - } - - /** - * Get the instance. - * - * @return unique instance of <tt>DSManager</tt> - */ - public static synchronized DSManager getInstance() - { - synchronized(sync) - { - if(instance == null) - { - long ptr = init(); - - if(ptr != 0) - { - instance = new DSManager(ptr); - } - } - - /* increment reference if object is valid */ - if(instance != null) - { - ref++; - } - } - return instance; - } - - /** - * Initialize and gather existing capture device. - * - * @return native pointer - */ - private static native long init(); - - /** - * Array of all <tt>DSCaptureDevice</tt> found - * on the OS. - */ - private DSCaptureDevice[] devices = null; - - /** - * Native pointer. - */ - private long ptr = 0; - - /** - * Constructor. - * - * @param ptr native pointer of DSManager - */ - private DSManager(long ptr) - { - if(ptr == 0) - { - throw new IllegalArgumentException("invalid ptr value (0)"); - } - - this.ptr = ptr; - } - - /** - * Get the array of capture devices. - * - * @return array of <tt>DSCaptureDevice</tt>s - */ - public DSCaptureDevice[] getCaptureDevices() - { - if(devices == null) - { - long nativeDevices[] = getCaptureDevices(ptr); - - if(nativeDevices != null && nativeDevices.length > 0) - { - devices = new DSCaptureDevice[nativeDevices.length]; - - for(int i = 0 ; i < nativeDevices.length ; i++) - { - devices[i] = new DSCaptureDevice(nativeDevices[i]); - } - } - else - { - devices = EMPTY_DEVICES; - } - } - return devices; - } - - /** - * Native method to get capture devices pointers. - * - * @param ptr native pointer of DSManager - * @return array of native pointer to DSCaptureDevice - */ - private native long[] getCaptureDevices(long ptr); -} diff --git a/src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java similarity index 76% rename from src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java rename to src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java index 49f2339704b165905a91238a4a4de78e9bd0a792..4ded28374b250e9838a2159e23b98f446a81abbc 100644 --- a/src/org/jitsi/impl/neomedia/directshow/DSCaptureDevice.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSCaptureDevice.java @@ -1,193 +1,204 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jitsi.impl.neomedia.directshow; - -/** - * DirectShow capture device. - * - * @author Sebastien Vincent - */ -public class DSCaptureDevice -{ - /** - * Empty array with <tt>DSFormat</tt> element type. Explicitly defined - * in order to avoid unnecessary allocations. - */ - private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0]; - - /** - * Get bytes from <tt>buf</tt> native pointer and copy them - * to <tt>ptr</tt> byte native pointer. - * - * @param ptr pointer to native data - * @param buf byte native pointer (see ByteBufferPool) - * @param length length of buf pointed by <tt>ptr</tt> - * @return length written to <tt>buf</tt> - */ - public static native int getBytes(long ptr, long buf, int length); - - /** - * Native pointer of <tt>DSCaptureDevice</tt>. - * - * This pointer is hold and will be released by <tt>DSManager</tt> - * singleton. - */ - private long ptr = 0; - - /** - * Constructor. - * - * @param ptr native pointer - */ - public DSCaptureDevice(long ptr) - { - /* do not allow 0 pointer value */ - if(ptr == 0) - throw new IllegalArgumentException("invalid ptr value (0)"); - - this.ptr = ptr; - } - - /** - * Stop and close the capture device. - */ - public void close() - { - close(ptr); - } - - /** - * Native method to close capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - */ - private native void close(long ptr); - - /** - * Get current format. - * - * @return current format used - */ - public DSFormat getFormat() - { - return getFormat(ptr); - } - - /** - * Native method to get format on the capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - * @return format current format - */ - private native DSFormat getFormat(long ptr); - - /** - * Get name of the capture device. - * - * @return name of the capture device - */ - public String getName() - { - return getName(ptr).trim(); - } - - /** - * Native method to get name of the capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - * @return name of the capture device - */ - private native String getName(long ptr); - - /** - * Get the supported video format this capture device supports. - * - * @return array of <tt>DSFormat</tt> - */ - public DSFormat[] getSupportedFormats() - { - DSFormat formats[] = getSupportedFormats(ptr); - - if(formats == null) - { - formats = EMPTY_FORMATS; - } - - return formats; - } - - /** - * Native method to get supported formats from capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - * @return array of native pointer corresponding to formats - */ - private native DSFormat[] getSupportedFormats(long ptr); - - /** - * Open and initialize the capture device. - */ - public void open() - { - open(ptr); - } - - /** - * Native method to open capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - */ - private native void open(long ptr); - - /** - * Set a delegate to use when a frame is received. - * @param delegate delegate - */ - public void setDelegate(GrabberDelegate delegate) - { - setDelegate(ptr, delegate); - } - - /** - * Native method to set a delegate to use when a frame is received. - * @param ptr native pointer - * @param delegate delegate - */ - public native void setDelegate(long ptr, GrabberDelegate delegate); - - /** - * Set format to use with this capture device. - * - * @param format format to set - */ - public void setFormat(DSFormat format) - { - setFormat(ptr, format); - } - - /** - * Native method to set format on the capture device. - * - * @param ptr native pointer of <tt>DSCaptureDevice</tt> - * @param format format to set - */ - private native void setFormat(long ptr, DSFormat format); - - /** - * Delegate class to handle grabbing frames. - */ - public static abstract class GrabberDelegate - { - /** - * Callback method when receiving frames. - * - * @param ptr native pointer to data - * @param length length of data - */ - public abstract void frameReceived(long ptr, int length); - } -} +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow; + +/** + * DirectShow capture device. + * + * @author Sebastien Vincent + * @author Lyubomir Marinov + */ +public class DSCaptureDevice +{ + /** + * Delegate class to handle grabbing frames. + */ + public static abstract class GrabberDelegate + { + /** + * Callback method when receiving frames. + * + * @param ptr native pointer to data + * @param length length of data + */ + public abstract void frameReceived(long ptr, int length); + } + + /** + * Empty array with <tt>DSFormat</tt> element type. Explicitly defined + * in order to avoid unnecessary allocations. + */ + private static final DSFormat EMPTY_FORMATS[] = new DSFormat[0]; + + /** + * Get bytes from <tt>buf</tt> native pointer and copy them + * to <tt>ptr</tt> byte native pointer. + * + * @param ptr pointer to native data + * @param buf byte native pointer (see ByteBufferPool) + * @param length length of buf pointed by <tt>ptr</tt> + * @return length written to <tt>buf</tt> + */ + public static native int getBytes(long ptr, long buf, int length); + + /** + * Native pointer of <tt>DSCaptureDevice</tt>. + * + * This pointer is hold and will be released by <tt>DSManager</tt> + * singleton. + */ + private final long ptr; + + /** + * Constructor. + * + * @param ptr native pointer + */ + public DSCaptureDevice(long ptr) + { + /* Do not allow 0/NULL pointer value. */ + if (ptr == 0) + throw new IllegalArgumentException("ptr"); + + this.ptr = ptr; + } + + /** + * Connects to this DirectShow video capture device. + */ + public void connect() + { + connect(ptr); + } + + /** + * Connects to the specified DirectShow video capture device + * + * @param ptr a pointer to a native <tt>DSCaptureDevice</tt> to connect to + */ + private native void connect(long ptr); + + /** + * Disconnects from this DirectShow video capture device. + */ + public void disconnect() + { + disconnect(ptr); + } + + /** + * Disconnects from a specific DirectShow video capture device + * + * @param ptr a pointer to a native <tt>DSCaptureDevice</tt> to disconnect + * from + */ + private native void disconnect(long ptr); + + /** + * Get current format. + * + * @return current format used + */ + public DSFormat getFormat() + { + return getFormat(ptr); + } + + /** + * Native method to get format on the capture device. + * + * @param ptr native pointer of <tt>DSCaptureDevice</tt> + * @return format current format + */ + private native DSFormat getFormat(long ptr); + + /** + * Get name of the capture device. + * + * @return name of the capture device + */ + public String getName() + { + return getName(ptr).trim(); + } + + /** + * Native method to get name of the capture device. + * + * @param ptr native pointer of <tt>DSCaptureDevice</tt> + * @return name of the capture device + */ + private native String getName(long ptr); + + /** + * Get the supported video format this capture device supports. + * + * @return array of <tt>DSFormat</tt> + */ + public DSFormat[] getSupportedFormats() + { + DSFormat formats[] = getSupportedFormats(ptr); + + return (formats == null) ? EMPTY_FORMATS : formats; + } + + /** + * Native method to get supported formats from capture device. + * + * @param ptr native pointer of <tt>DSCaptureDevice</tt> + * @return array of native pointer corresponding to formats + */ + private native DSFormat[] getSupportedFormats(long ptr); + + /** + * Set a delegate to use when a frame is received. + * @param delegate delegate + */ + public void setDelegate(GrabberDelegate delegate) + { + setDelegate(ptr, delegate); + } + + /** + * Native method to set a delegate to use when a frame is received. + * @param ptr native pointer + * @param delegate delegate + */ + private native void setDelegate(long ptr, GrabberDelegate delegate); + + /** + * Set format to use with this capture device. + * + * @param format format to set + */ + public void setFormat(DSFormat format) + { + setFormat(ptr, format); + } + + /** + * Native method to set format on the capture device. + * + * @param ptr native pointer of <tt>DSCaptureDevice</tt> + * @param format format to set + */ + private native void setFormat(long ptr, DSFormat format); + + public void start() + { + start(ptr); + } + + private native void start(long ptr); + + public void stop() + { + stop(ptr); + } + + private native void stop(long ptr); +} diff --git a/src/org/jitsi/impl/neomedia/directshow/DSFormat.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java similarity index 93% rename from src/org/jitsi/impl/neomedia/directshow/DSFormat.java rename to src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java index cd41c14b8c57ef72bb008d21af0f04b713c6775c..0df59af6bb81cacee9c87610a235cc5b87bb2464 100644 --- a/src/org/jitsi/impl/neomedia/directshow/DSFormat.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSFormat.java @@ -1,280 +1,278 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package org.jitsi.impl.neomedia.directshow; - -/** - * DirectShow video format. - * - * @author Sebastien Vincent - */ -public class DSFormat -{ - - /** - * The ARGB32 constant. - */ - public static final long ARGB32; - - /* supported formats */ - - /** - * The I420 constant. - */ - public static final long I420; - - /** - * The NV12 constant. - */ - public static final long NV12; - - /** - * The RGB24 constant. - */ - public static final long RGB24; - - /** - * The RGB32 constant. - */ - public static final long RGB32; - - /** - * The UYVY constant. - */ - public static final long UYVY; - - /** - * The Y411 constant. - */ - public static final long Y411; - - /** - * The Y41P constant. - */ - public static final long Y41P; - - /** - * The YUY2 constant. - */ - public static final long YUY2; - - static - { - System.loadLibrary("jndirectshow"); - - RGB24 = getRGB24PixelFormat(); - RGB32 = getRGB32PixelFormat(); - ARGB32 = getARGBPixelFormat(); - YUY2 = getYUY2PixelFormat(); - UYVY = getUYVYPixelFormat(); - NV12 = getNV12PixelFormat(); - Y411 = getY411PixelFormat(); - Y41P = getY41PPixelFormat(); - I420 = getI420PixelFormat(); - } - - /** - * Get the ARGB32 native pixel format - * - * @return ARGB32 native format value - */ - public static native long getARGBPixelFormat(); - - /** - * Get the AYUV native pixel format - * - * @return AYUV native format value - */ - public static native long getAYUVPixelFormat(); - - /** - * Get the I420 native pixel format - * - * @return I420 native format value - */ - public static native long getI420PixelFormat(); - - /** - * Get the IF09 native pixel format - * - * @return IF09 native format value - */ - public static native long getIF09PixelFormat(); - - /** - * Get the IMC1 native pixel format - * - * @return IMC1 native format value - */ - public static native long getIMC1PixelFormat(); - - /** - * Get the IMC2 native pixel format - * - * @return IMC2 native format value - */ - public static native long getIMC2PixelFormat(); - - /** - * Get the IMC3 native pixel format - * - * @return IMC3 native format value - */ - public static native long getIMC3PixelFormat(); - - /** - * Get the IMC4 native pixel format - * - * @return IMC4 native format value - */ - public static native long getIMC4PixelFormat(); - - /** - * Get the IYUV native pixel format - * - * @return IYUV native format value - */ - public static native long getIYUVPixelFormat(); - - /** - * Get the NV12 native pixel format - * - * @return NV12 native format value - */ - public static native long getNV12PixelFormat(); - - /* YUV */ - - /* RGB */ - /** - * Get the RGB24 native pixel format - * - * @return RGB24 native format value - */ - public static native long getRGB24PixelFormat(); - - /** - * Get the RGB32 native pixel format - * - * @return RGB32 native format value - */ - public static native long getRGB32PixelFormat(); - - /** - * Get the UYVY native pixel format - * - * @return UYVY native format value - */ - public static native long getUYVYPixelFormat(); - - /** - * Get the Y211 native pixel format - * - * @return Y211 native format value - */ - public static native long getY211PixelFormat(); - - /** - * Get the Y411 native pixel format - * - * @return Y411 native format value - */ - public static native long getY411PixelFormat(); - - /** - * Get the Y41P native pixel format - * - * @return Y41P native format value - */ - public static native long getY41PPixelFormat(); - - /** - * Get the YUY2 native pixel format - * - * @return YUY2 native format value - */ - public static native long getYUY2PixelFormat(); - - /** - * Get the YV12 native pixel format - * - * @return YV12 native format value - */ - public static native long getYV12PixelFormat(); - - /** - * Get the YVU9 native pixel format - * - * @return YVU9 native format value - */ - public static native long getYVU9PixelFormat(); - - /** - * Get the YVYU native pixel format - * - * @return YVYU native format value - */ - public static native long getYVYUPixelFormat(); - - /** - * Video height. - */ - private int height = 0; - - /** - * Color space. - */ - private long pixelFormat = -1; - - /** - * Video width. - */ - private int width = 0; - - /** - * Constructor. - * - * @param width video width - * @param height video height - * @param pixelFormat pixel format - */ - public DSFormat(int width, int height, long pixelFormat) - { - this.width = width; - this.height = height; - this.pixelFormat = pixelFormat; - } - - /** - * Get video height. - * - * @return video height - */ - public int getHeight() - { - return height; - } - - /** - * Get color space. - * - * @return color space - */ - public long getPixelFormat() - { - return pixelFormat; - } - - /** - * Get video width. - * - * @return video width - */ - public int getWidth() - { - return width; - } -} +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow; + +/** + * DirectShow video format. + * + * @author Sebastien Vincent + */ +public class DSFormat +{ + + /** + * The ARGB32 constant. + */ + public static final long ARGB32; + + /** + * The I420 constant. + */ + public static final long I420; + + /** + * The NV12 constant. + */ + public static final long NV12; + + /** + * The RGB24 constant. + */ + public static final long RGB24; + + /** + * The RGB32 constant. + */ + public static final long RGB32; + + /** + * The UYVY constant. + */ + public static final long UYVY; + + /** + * The Y411 constant. + */ + public static final long Y411; + + /** + * The Y41P constant. + */ + public static final long Y41P; + + /** + * The YUY2 constant. + */ + public static final long YUY2; + + static + { + System.loadLibrary("jndirectshow"); + + RGB24 = getRGB24PixelFormat(); + RGB32 = getRGB32PixelFormat(); + ARGB32 = getARGBPixelFormat(); + YUY2 = getYUY2PixelFormat(); + UYVY = getUYVYPixelFormat(); + NV12 = getNV12PixelFormat(); + Y411 = getY411PixelFormat(); + Y41P = getY41PPixelFormat(); + I420 = getI420PixelFormat(); + } + + /** + * Get the ARGB32 native pixel format + * + * @return ARGB32 native format value + */ + public static native long getARGBPixelFormat(); + + /** + * Get the AYUV native pixel format + * + * @return AYUV native format value + */ + public static native long getAYUVPixelFormat(); + + /** + * Get the I420 native pixel format + * + * @return I420 native format value + */ + public static native long getI420PixelFormat(); + + /** + * Get the IF09 native pixel format + * + * @return IF09 native format value + */ + public static native long getIF09PixelFormat(); + + /** + * Get the IMC1 native pixel format + * + * @return IMC1 native format value + */ + public static native long getIMC1PixelFormat(); + + /** + * Get the IMC2 native pixel format + * + * @return IMC2 native format value + */ + public static native long getIMC2PixelFormat(); + + /** + * Get the IMC3 native pixel format + * + * @return IMC3 native format value + */ + public static native long getIMC3PixelFormat(); + + /** + * Get the IMC4 native pixel format + * + * @return IMC4 native format value + */ + public static native long getIMC4PixelFormat(); + + /** + * Get the IYUV native pixel format + * + * @return IYUV native format value + */ + public static native long getIYUVPixelFormat(); + + /** + * Get the NV12 native pixel format + * + * @return NV12 native format value + */ + public static native long getNV12PixelFormat(); + + /* YUV */ + + /* RGB */ + /** + * Get the RGB24 native pixel format + * + * @return RGB24 native format value + */ + public static native long getRGB24PixelFormat(); + + /** + * Get the RGB32 native pixel format + * + * @return RGB32 native format value + */ + public static native long getRGB32PixelFormat(); + + /** + * Get the UYVY native pixel format + * + * @return UYVY native format value + */ + public static native long getUYVYPixelFormat(); + + /** + * Get the Y211 native pixel format + * + * @return Y211 native format value + */ + public static native long getY211PixelFormat(); + + /** + * Get the Y411 native pixel format + * + * @return Y411 native format value + */ + public static native long getY411PixelFormat(); + + /** + * Get the Y41P native pixel format + * + * @return Y41P native format value + */ + public static native long getY41PPixelFormat(); + + /** + * Get the YUY2 native pixel format + * + * @return YUY2 native format value + */ + public static native long getYUY2PixelFormat(); + + /** + * Get the YV12 native pixel format + * + * @return YV12 native format value + */ + public static native long getYV12PixelFormat(); + + /** + * Get the YVU9 native pixel format + * + * @return YVU9 native format value + */ + public static native long getYVU9PixelFormat(); + + /** + * Get the YVYU native pixel format + * + * @return YVYU native format value + */ + public static native long getYVYUPixelFormat(); + + /** + * Video height. + */ + private int height = 0; + + /** + * Color space. + */ + private long pixelFormat = -1; + + /** + * Video width. + */ + private int width = 0; + + /** + * Constructor. + * + * @param width video width + * @param height video height + * @param pixelFormat pixel format + */ + public DSFormat(int width, int height, long pixelFormat) + { + this.width = width; + this.height = height; + this.pixelFormat = pixelFormat; + } + + /** + * Get video height. + * + * @return video height + */ + public int getHeight() + { + return height; + } + + /** + * Get color space. + * + * @return color space + */ + public long getPixelFormat() + { + return pixelFormat; + } + + /** + * Get video width. + * + * @return video width + */ + public int getWidth() + { + return width; + } +} diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java new file mode 100644 index 0000000000000000000000000000000000000000..7136be827b41376c41b6a820d503bfdd3aeaa5b2 --- /dev/null +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java @@ -0,0 +1,111 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow; + +/** + * DirectShow capture device manager. + * + * <code> + * DSManager manager = new DSManager(); + * DSCaptureDevice[] devices = manager.getCaptureDevices(); + * + * // Utilize any DSCaptureDevice instance obtained through manager. + * + * manager.dispose(); + * + * // Do NOT utilize any DSCaptureDevice instance obtained through manager! + * </code> + * + * @author Sebastien Vincent + * @author Lyubomir Marinov + */ +public class DSManager +{ + /** + * Empty array of <tt>DSCaptureDevice</tt>s. Explicitly defined in order to + * avoid unnecessary allocations. + */ + private static DSCaptureDevice[] EMPTY_DEVICES = new DSCaptureDevice[0]; + + static + { + System.loadLibrary("jndirectshow"); + } + + /** + * Delete native pointer. + * + * @param ptr native pointer to delete + */ + private static native void destroy(long ptr); + + /** + * Initialize and gather existing capture device. + * + * @return native pointer + */ + private static native long init(); + + /** + * Array of all <tt>DSCaptureDevice</tt>s found on the OS. + */ + private DSCaptureDevice[] captureDevices; + + /** + * Native pointer. + */ + private final long ptr; + + /** + * Constructor. + */ + public DSManager() + { + ptr = init(); + if (ptr == 0) + throw new IllegalStateException("ptr"); + } + + /** + * Dispose the object. + */ + public void dispose() + { + destroy(ptr); + } + + /** + * Get the array of capture devices. + * + * @return array of <tt>DSCaptureDevice</tt>s + */ + public DSCaptureDevice[] getCaptureDevices() + { + if (captureDevices == null) + { + long ptrs[] = getCaptureDevices(ptr); + + if ((ptrs != null) && (ptrs.length != 0)) + { + captureDevices = new DSCaptureDevice[ptrs.length]; + for (int i = 0 ; i < ptrs.length ; i++) + captureDevices[i] = new DSCaptureDevice(ptrs[i]); + } + else + captureDevices = EMPTY_DEVICES; + } + return captureDevices; + } + + /** + * Native method to get capture devices pointers. + * + * @param ptr native pointer of DSManager + * @return array of native pointer to DSCaptureDevice + */ + private native long[] getCaptureDevices(long ptr); +} diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java index 4c1721501fb99b0479cfd4f401b77edae834415f..b598eab38a6bf64e28cc68c04b185e82cfa0c9bb 100644 --- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java @@ -13,13 +13,11 @@ import javax.media.*; import javax.media.control.*; -import javax.media.format.*; import org.jitsi.impl.neomedia.codec.*; import org.jitsi.impl.neomedia.codec.video.*; import org.jitsi.impl.neomedia.control.*; import org.jitsi.impl.neomedia.device.*; -import org.jitsi.impl.neomedia.directshow.*; import org.jitsi.impl.neomedia.jmfext.media.protocol.*; import org.jitsi.util.*; @@ -100,30 +98,18 @@ public static long getFFmpegPixFmt(long dsPixFmt) /** * DirectShow capture device. */ - private DSCaptureDevice device = null; - - /** - * Delegate grabber. Each frame captured by device will be pass through this - * grabber. - */ - private DSCaptureDevice.GrabberDelegate grabber = null; + private DSCaptureDevice device; /** * DirectShow manager. */ - private DSManager manager = null; - - /** - * Last known native DirectShow format. - */ - private DSFormat nativeFormat = null; + private DSManager manager; /** * Constructor. */ public DataSource() { - manager = DSManager.getInstance(); } /** @@ -135,8 +121,6 @@ public DataSource() public DataSource(MediaLocator locator) { super(locator); - - manager = DSManager.getInstance(); } /** @@ -201,19 +185,23 @@ protected AbstractPushBufferStream createStream( if (logger.isTraceEnabled()) { - DSFormat deviceFmts[] = device.getSupportedFormats(); + DSCaptureDevice device = this.device; - for (DSFormat deviceFmt : deviceFmts) + if (device != null) { - logger.trace( - "width= " + deviceFmt.getWidth() - + ", height= " + deviceFmt.getHeight() - + ", pixelFormat= " + deviceFmt.getPixelFormat()); + DSFormat supportedFormats[] = device.getSupportedFormats(); + + for (DSFormat supportedFormat : supportedFormats) + { + logger.trace( + "width= " + supportedFormat.getWidth() + + ", height= " + supportedFormat.getHeight() + + ", pixelFormat= " + + supportedFormat.getPixelFormat()); + } } } - grabber = stream.grabber; - return stream; } @@ -227,17 +215,41 @@ protected AbstractPushBufferStream createStream( * @see AbstractPushBufferCaptureDevice#doConnect() */ @Override - protected void doConnect() throws IOException + protected void doConnect() + throws IOException { - if (logger.isInfoEnabled()) - logger.info("doConnect"); + super.doConnect(); - if(manager == null) - manager = DSManager.getInstance(); + boolean connected = false; - setLocator(getLocator()); + try + { + DSCaptureDevice device = getDevice(); - super.doConnect(); + device.connect(); + + synchronized (getStreamSyncRoot()) + { + for (Object stream : getStreams()) + ((DirectShowStream) stream).setDevice(device); + } + + connected = true; + } + finally + { + if (!connected) + { + /* + * The connect attempt has failed but it may have been + * successful up to the point of failure thus partially + * modifying the state. The disconnect procedure is prepared to + * deal with a partially modified state and will restore it to + * its pristine form. + */ + doDisconnect(); + } + } } /** @@ -249,61 +261,93 @@ protected void doConnect() throws IOException @Override protected void doDisconnect() { - if (logger.isInfoEnabled()) - logger.info("doDisconnect"); - - super.doDisconnect(); - - if(manager != null) + try { - device.setDelegate(null); - device = null; + synchronized (getStreamSyncRoot()) + { + for (Object stream : getStreams()) + { + try + { + ((DirectShowStream) stream).setDevice(null); + } + catch (IOException ioe) + { + logger.error( + "Failed to disconnect " + + stream.getClass().getName(), + ioe); + } + } + } + } + finally + { + if (device != null) + { + device.disconnect(); + device = null; + } + if (manager != null) + { + manager.dispose(); + manager = null; + } - DSManager.dispose(); - manager = null; + super.doDisconnect(); } } - /** - * Starts the transfer of media data from this <tt>DataSource</tt>. - * - * @throws IOException if anything goes wrong while starting the transfer of - * media data from this <tt>DataSource</tt> - * @see AbstractPushBufferCaptureDevice#doStart() - */ - @Override - protected void doStart() throws IOException + private DSCaptureDevice getDevice() { - if (logger.isInfoEnabled()) - logger.info("start"); + DSCaptureDevice device = this.device; - /* Open and start the capture. */ - device.open(); - if(nativeFormat != null) - device.setFormat(nativeFormat); + if (device == null) + { + MediaLocator locator = getLocator(); - device.setDelegate(grabber); + if (locator == null) + throw new IllegalStateException("locator"); + if (!locator.getProtocol().equalsIgnoreCase( + DeviceSystem.LOCATOR_PROTOCOL_DIRECTSHOW)) + throw new IllegalStateException("locator.protocol"); - super.doStart(); - } + String remainder = locator.getRemainder(); - /** - * Stops the transfer of media data from this <tt>DataSource</tt>. - * - * @throws IOException if anything goes wrong while stopping the transfer of - * media data from this <tt>DataSource</tt> - * @see AbstractPushBufferCaptureDevice#doStop() - */ - @Override - protected void doStop() throws IOException - { - if (logger.isInfoEnabled()) - logger.info("stop"); + if (remainder == null) + throw new IllegalStateException("locator.remainder"); - super.doStop(); + if (manager == null) + manager = new DSManager(); + try + { + /* + * Find the device specified by the locator using matching by + * name. + */ + for (DSCaptureDevice d : manager.getCaptureDevices()) + { + if (remainder.equals(d.getName())) + { + device = d; + break; + } + } - /* Stop and close the capture. */ - device.close(); + if (device != null) + this.device = device; + } + finally + { + if (this.device == null) + { + manager.dispose(); + manager = null; + } + } + } + + return device; } /** @@ -324,8 +368,10 @@ protected void doStop() throws IOException @Override protected Format[] getSupportedFormats(int streamIndex) { - if(device == null) - return new Format[0]; + DSCaptureDevice device = this.device; + + if (device == null) + return super.getSupportedFormats(streamIndex); DSFormat[] deviceFmts = device.getSupportedFormats(); List<Format> fmts = new ArrayList<Format>(deviceFmts.length); @@ -346,18 +392,6 @@ protected Format[] getSupportedFormats(int streamIndex) return fmts.toArray(new Format[fmts.size()]); } - /** - * Sets the <tt>DSCaptureDevice</tt> which represents the media source of - * this <tt>DataSource</tt>. - * - * @param device the <tt>DSCaptureDevice</tt> which represents the media - * source of this <tt>DataSource</tt> - */ - private void setDevice(DSCaptureDevice device) - { - this.device = device; - } - /** * Attempts to set the <tt>Format</tt> to be reported by the * <tt>FormatControl</tt> of a <tt>PushBufferStream</tt> at a specific @@ -382,87 +416,31 @@ protected Format setFormat( int streamIndex, Format oldValue, Format newValue) { - if(newValue instanceof VideoFormat) + if (newValue instanceof AVFrameFormat) { - if(newValue instanceof AVFrameFormat) - { - AVFrameFormat avFrameFormat = (AVFrameFormat) newValue; - long pixFmt = avFrameFormat.getDeviceSystemPixFmt(); + AVFrameFormat avFrameFormat = (AVFrameFormat) newValue; + long pixFmt = avFrameFormat.getDeviceSystemPixFmt(); - if(pixFmt != -1) - { - Dimension size = avFrameFormat.getSize(); - - /* - * We will set the native format in doStart() because a - * connect-disconnect-connect sequence of the native capture - * device may reorder its formats in a different way. - * Consequently, in the absence of further calls to - * setFormat() by JMF, a crash may occur later (typically, - * during scaling) because of a wrong format. - */ - nativeFormat - = new DSFormat(size.width, size.height, pixFmt); - } - } - - // This DataSource supports setFormat. - return newValue; - } - else - return super.setFormat(streamIndex, oldValue, newValue); - } - - /** - * Sets the <tt>MediaLocator</tt> which specifies the media source of this - * <tt>DataSource</tt>. - * - * @param locator the <tt>MediaLocator</tt> which specifies the media source - * of this <tt>DataSource</tt> - * @see DataSource#setLocator(MediaLocator) - */ - @Override - public void setLocator(MediaLocator locator) - { - DSCaptureDevice device = null; - logger.info("set locator to " + locator); - - if(getLocator() == null) - super.setLocator(locator); - locator = getLocator(); - logger.info("getLocator() returns " + locator); - - if((locator != null) && - DeviceSystem.LOCATOR_PROTOCOL_DIRECTSHOW.equalsIgnoreCase( - locator.getProtocol())) - { - DSCaptureDevice[] devices = manager.getCaptureDevices(); - - logger.info("Search directshow device..."); - - /* find device */ - for(int i = 0 ; i < devices.length ; i++) + if (pixFmt != -1) { - if(devices[i].getName().equals(locator.getRemainder())) + Dimension size = avFrameFormat.getSize(); + + /* + * We will set the native format in doStart() because a + * connect-disconnect-connect sequence of the native capture + * device may reorder its formats in a different way. + * Consequently, in the absence of further calls to + * setFormat() by JMF, a crash may occur later (typically, + * during scaling) because of a wrong format. + */ + if (size != null) { - device = devices[i]; - logger.info("Set directshow device: " + device); - break; + // This DataSource supports setFormat. + return newValue; } } - - if(device == null) - { - logger.info("No devices matches locator's remainder: " + - locator.getRemainder()); - } } - else - { - logger.info( - "MediaLocator either null or does not have right protocol"); - device = null; - } - setDevice(device); + + return super.setFormat(streamIndex, oldValue, newValue); } } diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java index 84c717a573131af023d3040a52bf65c20e280af3..f338b19e69f664eb7ad1a3875c3c3f420c899a69 100644 --- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java @@ -6,15 +6,14 @@ */ package org.jitsi.impl.neomedia.jmfext.media.protocol.directshow; +import java.awt.*; import java.io.*; import javax.media.*; import javax.media.control.*; -import javax.media.format.*; import javax.media.protocol.*; import org.jitsi.impl.neomedia.codec.video.*; -import org.jitsi.impl.neomedia.directshow.*; import org.jitsi.impl.neomedia.jmfext.media.protocol.*; /** @@ -32,7 +31,7 @@ public class DirectShowStream * ourselves because DirectShow will buffer them all and the video will * be late. */ - private boolean automaticallyDropsLateVideoFrames = false; + private final boolean automaticallyDropsLateVideoFrames = false; /** * The pool of <tt>ByteBuffer</tt>s this instances is using to transfer the @@ -57,24 +56,30 @@ public class DirectShowStream */ private long dataTimeStamp; + /** + * The <tt>DSCaptureDevice</tt> which identifies the DirectShow video + * capture device this <tt>SourceStream</tt> is to capture data from. + */ + private DSCaptureDevice device; + /** * The last-known <tt>Format</tt> of the media data made available by this * <tt>PushBufferStream</tt>. */ - private final Format format; + private Format format; /** * Delegate class to handle video data. */ - final DSCaptureDevice.GrabberDelegate grabber + private final DSCaptureDevice.GrabberDelegate grabber = new DSCaptureDevice.GrabberDelegate() - { - @Override - public void frameReceived(long ptr, int length) - { - processFrame(ptr, length); - } - }; + { + @Override + public void frameReceived(long ptr, int length) + { + processFrame(ptr, length); + } + }; /** * The captured media data to become the value of {@link #data} as soon as @@ -111,8 +116,70 @@ public void frameReceived(long ptr, int length) DirectShowStream(DataSource dataSource, FormatControl formatControl) { super(dataSource, formatControl); + } + + /** + * Connects this <tt>SourceStream</tt> to the DirectShow video capture + * device identified by {@link #device}. + * + * @throws IOException if anything goes wrong while this + * <tt>SourceStream</tt> connects to the DirectShow video capture device + * identified by <tt>device</tt> + */ + private void connect() + throws IOException + { + if (device == null) + throw new IOException("device == null"); + else + { + Format format = getFormat(); + + if (format instanceof AVFrameFormat) + { + AVFrameFormat avFrameFormat = (AVFrameFormat) format; + Dimension size = avFrameFormat.getSize(); + + if (size == null) + throw new IOException("format.size == null"); + else + { + device.setFormat( + new DSFormat( + size.width, size.height, + avFrameFormat.getDeviceSystemPixFmt())); + this.format = format; + } + } + else + throw new IOException("!(format instanceof AVFrameFormat)"); - format = (VideoFormat) formatControl.getFormat(); + device.setDelegate(grabber); + } + } + + /** + * Disconnects this <tt>SourceStream</tt> from the DirectShow video capture + * device it has previously connected to during the execution of + * {@link #connect()}. + * + * @throws IOException if anything goes wrong while this + * <tt>SourceStream</tt> disconnects from the DirectShow video capture + * device it has previously connected to during the execution of + * <tt>connect()</tt> + */ + private void disconnect() + throws IOException + { + try + { + stop(); + } + finally + { + if (device != null) + device.setDelegate(null); + } } /** @@ -128,7 +195,7 @@ public void frameReceived(long ptr, int length) @Override protected Format doGetFormat() { - return (this.format == null) ? super.doGetFormat() : this.format; + return (format == null) ? super.doGetFormat() : format; } /** @@ -392,6 +459,31 @@ private void runInTransferDataThread() } } + /** + * Sets the <tt>DSCaptureDevice</tt> of this instance which identifies the + * DirectShow video capture device this <tt>SourceStream</tt> is to capture + * data from. + * + * @param device a <tt>DSCaptureDevice</tt> which identifies the DirectShow + * video capture device this <tt>SourceStream</tt> is to capture data from + * @throws IOException if anything goes wrong while setting the specified + * <tt>device</tt> on this instance + */ + void setDevice(DSCaptureDevice device) + throws IOException + { + if (this.device != device) + { + if (this.device != null) + disconnect(); + + this.device = device; + + if (this.device != null) + connect(); + } + } + /** * Starts the transfer of media data from this <tt>PushBufferStream</tt>. * @@ -404,18 +496,36 @@ public void start() { super.start(); - if(!automaticallyDropsLateVideoFrames) + boolean started = false; + + try { - transferDataThread - = new Thread(getClass().getSimpleName()) + if(!automaticallyDropsLateVideoFrames) + { + if (transferDataThread == null) { - @Override - public void run() - { - runInTransferDataThread(); - } - }; - transferDataThread.start(); + transferDataThread + = new Thread(getClass().getSimpleName()) + { + @Override + public void run() + { + runInTransferDataThread(); + } + }; + transferDataThread.start(); + } + } + + if (device != null) + device.start(); + + started = true; + } + finally + { + if (!started) + stop(); } } @@ -431,6 +541,9 @@ public void stop() { try { + if (device != null) + device.stop(); + transferDataThread = null; synchronized (dataSyncRoot)