From 6a396e0261796e118b29ef90eef74c97e01df415 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov <lyubomir.marinov@jitsi.org> Date: Thu, 23 May 2013 00:18:27 +0300 Subject: [PATCH] Reduces the numbers of times that the camera gets opened and closed on Windows to the minimum, strives to be more thorough about the opening, closing, disposing in an attempt to mitigate issues which could cause the camera to remain open. --- lib/native/windows-64/jndirectshow.dll | Bin 250733 -> 251310 bytes lib/native/windows/jndirectshow.dll | Bin 241220 -> 242309 bytes .../windows/directshow/DSCaptureDevice.cpp | 142 +---- .../windows/directshow/DSCaptureDevice.h | 24 +- src/native/windows/directshow/DSFormat.h | 29 + src/native/windows/directshow/DSManager.cpp | 95 +-- src/native/windows/directshow/DSManager.h | 60 +- src/native/windows/directshow/VideoFormat.h | 29 - ...impl_neomedia_directshow_DSCaptureDevice.h | 77 --- ...itsi_impl_neomedia_directshow_DSFormat.cpp | 132 ----- ..._jitsi_impl_neomedia_directshow_DSFormat.h | 173 ------ ...jitsi_impl_neomedia_directshow_DSManager.h | 37 -- ...a_protocol_directshow_DSCaptureDevice.cpp} | 207 ++++--- ...edia_protocol_directshow_DSCaptureDevice.h | 93 +++ ...ext_media_protocol_directshow_DSFormat.cpp | 132 +++++ ...mfext_media_protocol_directshow_DSFormat.h | 173 ++++++ ...t_media_protocol_directshow_DSManager.cpp} | 36 +- ...fext_media_protocol_directshow_DSManager.h | 37 ++ .../neomedia/device/DirectShowSystem.java | 111 ++-- .../impl/neomedia/directshow/DSManager.java | 181 ------ .../protocol}/directshow/DSCaptureDevice.java | 397 +++++++------ .../media/protocol}/directshow/DSFormat.java | 558 +++++++++--------- .../media/protocol/directshow/DSManager.java | 111 ++++ .../media/protocol/directshow/DataSource.java | 308 +++++----- .../protocol/directshow/DirectShowStream.java | 161 ++++- 25 files changed, 1588 insertions(+), 1715 deletions(-) create mode 100644 src/native/windows/directshow/DSFormat.h delete mode 100644 src/native/windows/directshow/VideoFormat.h delete mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSCaptureDevice.h delete mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.cpp delete mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSFormat.h delete mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_directshow_DSManager.h rename src/native/windows/directshow/{org_jitsi_impl_neomedia_directshow_DSCaptureDevice.cpp => org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.cpp} (77%) create mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSCaptureDevice.h create mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.cpp create mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSFormat.h rename src/native/windows/directshow/{org_jitsi_impl_neomedia_directshow_DSManager.cpp => org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.cpp} (69%) create mode 100644 src/native/windows/directshow/org_jitsi_impl_neomedia_jmfext_media_protocol_directshow_DSManager.h delete mode 100644 src/org/jitsi/impl/neomedia/directshow/DSManager.java rename src/org/jitsi/impl/neomedia/{ => jmfext/media/protocol}/directshow/DSCaptureDevice.java (76%) rename src/org/jitsi/impl/neomedia/{ => jmfext/media/protocol}/directshow/DSFormat.java (93%) create mode 100644 src/org/jitsi/impl/neomedia/jmfext/media/protocol/directshow/DSManager.java diff --git a/lib/native/windows-64/jndirectshow.dll b/lib/native/windows-64/jndirectshow.dll index 56909b7e8d1fda887fcd3288f60657cf6e8aaeee..06e7a87b0f5e032b010c5ecfafa7c18e87f22e25 100644 GIT binary patch delta 69875 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 delta 69140 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 QrS^6U9i3X#J=E*}04x^F$p8QV diff --git a/lib/native/windows/jndirectshow.dll b/lib/native/windows/jndirectshow.dll index e1ed7a899a6d1432a1a443a401762725442913e9..3326eec6925c12f6feb090d8b69682b4c8f543a3 100644 GIT binary patch delta 60476 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 Sj#v$&?`_Gco0FYh7yTdM`4bHQ delta 59511 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 diff --git a/src/native/windows/directshow/DSCaptureDevice.cpp b/src/native/windows/directshow/DSCaptureDevice.cpp index 94d54763..2ee47577 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 cda7ad01..6af3ecbe 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 00000000..cfa9c332 --- /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 1ec6a61a..ad90c639 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 e68719d8..5d49c07e 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 39fc7c5d..00000000 --- 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 fd30b11f..00000000 --- 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 01fc0d68..00000000 --- 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 4ad0c5e3..00000000 --- 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 f045e21b..00000000 --- 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 45f87dd3..6f7926bf 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 00000000..d0a90248 --- /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 00000000..613f3945 --- /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 00000000..a29c5ba0 --- /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 b938b507..ab218aa7 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 00000000..c43419ef --- /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 b85f9f99..efe82c6b 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 858ed4c2..00000000 --- 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 49f23397..4ded2837 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 cd41c14b..0df59af6 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 00000000..7136be82 --- /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 4c172150..b598eab3 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 84c717a5..f338b19e 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) -- GitLab