diff options
Diffstat (limited to 'plugins/pluginDirectShow')
51 files changed, 5568 insertions, 5407 deletions
diff --git a/plugins/pluginDirectShow/dllmain_dshow.cxx b/plugins/pluginDirectShow/dllmain_dshow.cxx index 2b1eda8..b8a18d7 100755 --- a/plugins/pluginDirectShow/dllmain_dshow.cxx +++ b/plugins/pluginDirectShow/dllmain_dshow.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -42,13 +42,14 @@ extern const tmedia_consumer_plugin_def_t *plugin_video_dshow_consumer_plugin_de extern const tmedia_producer_plugin_def_t *plugin_video_dshow_producer_plugin_def_t; extern const tmedia_producer_plugin_def_t *plugin_screencast_dshow_producer_plugin_def_t; -CFactoryTemplate g_Templates[]= -{ { L"" -, NULL -, NULL -, NULL -, NULL -} +CFactoryTemplate g_Templates[]= { + { + L"" + , NULL + , NULL + , NULL + , NULL + } }; int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]); @@ -56,101 +57,90 @@ int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } #endif -typedef enum PLUGIN_INDEX_E -{ - PLUGIN_INDEX_VIDEO_CONSUMER, - PLUGIN_INDEX_VIDEO_PRODUCER, +typedef enum PLUGIN_INDEX_E { + PLUGIN_INDEX_VIDEO_CONSUMER, + PLUGIN_INDEX_VIDEO_PRODUCER, #if 0 - PLUGIN_INDEX_SCREENCAST_PRODUCER, + PLUGIN_INDEX_SCREENCAST_PRODUCER, #endif - PLUGIN_INDEX_COUNT + PLUGIN_INDEX_COUNT } PLUGIN_INDEX_T; int __plugin_get_def_count() { - return PLUGIN_INDEX_COUNT; + return PLUGIN_INDEX_COUNT; } tsk_plugin_def_type_t __plugin_get_def_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_VIDEO_CONSUMER: - return IsD3D9Supported() ? tsk_plugin_def_type_consumer : tsk_plugin_def_type_none; - case PLUGIN_INDEX_VIDEO_PRODUCER: + switch(index) { + case PLUGIN_INDEX_VIDEO_CONSUMER: + return IsD3D9Supported() ? tsk_plugin_def_type_consumer : tsk_plugin_def_type_none; + case PLUGIN_INDEX_VIDEO_PRODUCER: #if ENABLE_SCREENCAST - case PLUGIN_INDEX_SCREENCAST_PRODUCER: + case PLUGIN_INDEX_SCREENCAST_PRODUCER: #endif - return tsk_plugin_def_type_producer; - default: - { - TSK_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_type_none; - } - } + return tsk_plugin_def_type_producer; + default: { + TSK_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_type_none; + } + } } tsk_plugin_def_media_type_t __plugin_get_def_media_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_VIDEO_CONSUMER: - { - return IsD3D9Supported() ? tsk_plugin_def_media_type_video : tsk_plugin_def_media_type_none; - } - case PLUGIN_INDEX_VIDEO_PRODUCER: - { - return tsk_plugin_def_media_type_video; - } + switch(index) { + case PLUGIN_INDEX_VIDEO_CONSUMER: { + return IsD3D9Supported() ? tsk_plugin_def_media_type_video : tsk_plugin_def_media_type_none; + } + case PLUGIN_INDEX_VIDEO_PRODUCER: { + return tsk_plugin_def_media_type_video; + } #if ENABLE_SCREENCAST - case PLUGIN_INDEX_SCREENCAST_PRODUCER: - { - return tsk_plugin_def_media_type_screencast; - } + case PLUGIN_INDEX_SCREENCAST_PRODUCER: { + return tsk_plugin_def_media_type_screencast; + } #endif - default: - { - TSK_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_media_type_none; - } - } + default: { + TSK_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_media_type_none; + } + } } tsk_plugin_def_ptr_const_t __plugin_get_def_at(int index) { - switch(index){ - case PLUGIN_INDEX_VIDEO_CONSUMER: - { - return IsD3D9Supported() ? plugin_video_dshow_consumer_plugin_def_t : tsk_null; - } - case PLUGIN_INDEX_VIDEO_PRODUCER: - { - return plugin_video_dshow_producer_plugin_def_t; - } + switch(index) { + case PLUGIN_INDEX_VIDEO_CONSUMER: { + return IsD3D9Supported() ? plugin_video_dshow_consumer_plugin_def_t : tsk_null; + } + case PLUGIN_INDEX_VIDEO_PRODUCER: { + return plugin_video_dshow_producer_plugin_def_t; + } #if ENABLE_SCREENCAST - case PLUGIN_INDEX_SCREENCAST_PRODUCER: - { - return plugin_screencast_dshow_producer_plugin_def_t; - } + case PLUGIN_INDEX_SCREENCAST_PRODUCER: { + return plugin_screencast_dshow_producer_plugin_def_t; + } #endif - default: - { - TSK_DEBUG_ERROR("No plugin at index %d", index); - return tsk_null; - } - } + default: { + TSK_DEBUG_ERROR("No plugin at index %d", index); + return tsk_null; + } + } } diff --git a/plugins/pluginDirectShow/internals/DSBaseCaptureGraph.h b/plugins/pluginDirectShow/internals/DSBaseCaptureGraph.h index 1817fb5..c2d8455 100755 --- a/plugins/pluginDirectShow/internals/DSBaseCaptureGraph.h +++ b/plugins/pluginDirectShow/internals/DSBaseCaptureGraph.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -36,29 +36,29 @@ class DSBaseCaptureGraph { public: #if defined(_WIN32_WCE) - DSBaseCaptureGraph(DSISampleGrabberCB* callback, HRESULT *hr) {} + DSBaseCaptureGraph(DSISampleGrabberCB* callback, HRESULT *hr) {} #else - DSBaseCaptureGraph(ISampleGrabberCB* callback, HRESULT *hr) {} + DSBaseCaptureGraph(ISampleGrabberCB* callback, HRESULT *hr) {} #endif - virtual ~DSBaseCaptureGraph() {} + virtual ~DSBaseCaptureGraph() {} - virtual std::vector<DSCaptureFormat> *getFormats() = 0; + virtual std::vector<DSCaptureFormat> *getFormats() = 0; - virtual HRESULT setSource(const std::string &devicePath) = 0; - virtual HRESULT setParameters(DSCaptureFormat *format, int framerate) = 0; + virtual HRESULT setSource(const std::string &devicePath) = 0; + virtual HRESULT setParameters(DSCaptureFormat *format, int framerate) = 0; - virtual HRESULT connect() = 0; - virtual HRESULT disconnect() = 0; + virtual HRESULT connect() = 0; + virtual HRESULT disconnect() = 0; - virtual HRESULT start() = 0; - virtual HRESULT stop() = 0; - virtual HRESULT pause() = 0; - virtual bool isRunning() = 0; - virtual bool isPaused() = 0; + virtual HRESULT start() = 0; + virtual HRESULT stop() = 0; + virtual HRESULT pause() = 0; + virtual bool isRunning() = 0; + virtual bool isPaused() = 0; - virtual std::string getDeviceId() const = 0; + virtual std::string getDeviceId() const = 0; - virtual HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType) = 0; + virtual HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType) = 0; }; #endif /* PLUGIN_DSHOW_DSBASECAPTUREGRAPH_H */ diff --git a/plugins/pluginDirectShow/internals/DSBufferWriter.h b/plugins/pluginDirectShow/internals/DSBufferWriter.h index dbe1484..70c1f23 100755 --- a/plugins/pluginDirectShow/internals/DSBufferWriter.h +++ b/plugins/pluginDirectShow/internals/DSBufferWriter.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -30,19 +30,19 @@ #endif // {27AD9929-E4E7-423b-8BDD-8AF5AC894DE0} -TDSHOW_DEFINE_GUID(IID_DSBufferWriter, +TDSHOW_DEFINE_GUID(IID_DSBufferWriter, 0x27ad9929, 0xe4e7, 0x423b, 0x8b, 0xdd, 0x8a, 0xf5, 0xac, 0x89, 0x4d, 0xe0); */ class DSBufferWriter #ifndef _WIN32_WCE - : public IUnknown + : public IUnknown #endif { public: - virtual void setBuffer (void* pBuffer, int size) = 0; - virtual HRESULT setImageFormat(UINT width, UINT height/*, GUID subType, UINT fps*/) = 0; + virtual void setBuffer (void* pBuffer, int size) = 0; + virtual HRESULT setImageFormat(UINT width, UINT height/*, GUID subType, UINT fps*/) = 0; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSCaptureFormat.cxx b/plugins/pluginDirectShow/internals/DSCaptureFormat.cxx index 378a215..781101d 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureFormat.cxx +++ b/plugins/pluginDirectShow/internals/DSCaptureFormat.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -21,40 +21,60 @@ int DSCaptureFormat::getMatchScore(int w, int h) { - int factor; + int factor; - if ((w == width) && (h = height)){ - factor = 100; - } - else if ((w > this->width) && (h > this->height)){ - factor = 0; - } - else{ - factor = (50 * w) / this->width + (50 * h) / this->height; - } + if ((w == width) && (h = height)) { + factor = 100; + } + else if ((w > this->width) && (h > this->height)) { + factor = 0; + } + else { + factor = (50 * w) / this->width + (50 * h) / this->height; + } - if (isRGB()){ - factor *= 2; - } + if (isRGB()) { + factor *= 2; + } - return factor; + return factor; } bool DSCaptureFormat::isRGB() { - // Order used is optimized for most used RGB types - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB32)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB24)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB565)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB555)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB8)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB4)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB1)) return true; + // Order used is optimized for most used RGB types + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB32)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB24)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB565)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB555)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB8)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB4)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_RGB1)) { + return true; + } #ifndef _WIN32_WCE - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB32)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB4444)) return true; - if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB1555)) return true; + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB32)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB4444)) { + return true; + } + if (IsEqualGUID(this->chroma, MEDIASUBTYPE_ARGB1555)) { + return true; + } #endif - return false; + return false; } diff --git a/plugins/pluginDirectShow/internals/DSCaptureFormat.h b/plugins/pluginDirectShow/internals/DSCaptureFormat.h index 5e1cabb..45497cb 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureFormat.h +++ b/plugins/pluginDirectShow/internals/DSCaptureFormat.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -25,22 +25,30 @@ class DSCaptureFormat { public: - DSCaptureFormat(int w, int h, int f, GUID c) : width(w), height(h), fps(f), chroma(c) {}; - virtual ~DSCaptureFormat() {}; - - int getWidth() { return this->width; }; - int getHeight() { return this->height; }; - int getFramerate() { return this->fps; }; - GUID getChroma() { return this->chroma; }; - - int getMatchScore(int w, int h); - bool isRGB(); + DSCaptureFormat(int w, int h, int f, GUID c) : width(w), height(h), fps(f), chroma(c) {}; + virtual ~DSCaptureFormat() {}; + + int getWidth() { + return this->width; + }; + int getHeight() { + return this->height; + }; + int getFramerate() { + return this->fps; + }; + GUID getChroma() { + return this->chroma; + }; + + int getMatchScore(int w, int h); + bool isRGB(); private: - int width; - int height; - int fps; - GUID chroma; + int width; + int height; + int fps; + GUID chroma; }; diff --git a/plugins/pluginDirectShow/internals/DSCaptureGraph.cxx b/plugins/pluginDirectShow/internals/DSCaptureGraph.cxx index 3da6da1..1b46b72 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureGraph.cxx +++ b/plugins/pluginDirectShow/internals/DSCaptureGraph.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -27,149 +27,159 @@ using namespace std; #ifdef _WIN32_WCE DSCaptureGraph::DSCaptureGraph(DSISampleGrabberCB* callback, HRESULT *hr) -: DSBaseCaptureGraph(callback, hr) + : DSBaseCaptureGraph(callback, hr) #else DSCaptureGraph::DSCaptureGraph(ISampleGrabberCB* callback, HRESULT *hr) -: DSBaseCaptureGraph(callback, hr) + : DSBaseCaptureGraph(callback, hr) #endif { - this->grabberCallback = callback; + this->grabberCallback = callback; - this->captureFormat = NULL; - this->captureGraphBuilder = NULL; - this->graphBuilder = NULL; + this->captureFormat = NULL; + this->captureGraphBuilder = NULL; + this->graphBuilder = NULL; - this->sourceFilter = NULL; - this->sampleGrabberFilter = NULL; + this->sourceFilter = NULL; + this->sampleGrabberFilter = NULL; #ifdef _WIN32_WCE - this->colorConvertor565 = NULL; + this->colorConvertor565 = NULL; #else - this->frameRateFilter = NULL; + this->frameRateFilter = NULL; #endif - this->nullRendererFilter = NULL; - this->grabberController = NULL; - this->mediaController = NULL; - this->mediaEventController = NULL; + this->nullRendererFilter = NULL; + this->grabberController = NULL; + this->mediaController = NULL; + this->mediaEventController = NULL; - this->streamConfiguration = NULL; + this->streamConfiguration = NULL; - this->running = FALSE; - this->paused = FALSE; - this->deviceId = ""; + this->running = FALSE; + this->paused = FALSE; + this->deviceId = ""; - *hr = this->createCaptureGraph(); + *hr = this->createCaptureGraph(); } DSCaptureGraph::~DSCaptureGraph() { - SAFE_RELEASE(this->streamConfiguration); + SAFE_RELEASE(this->streamConfiguration); - SAFE_RELEASE(this->mediaEventController); - SAFE_RELEASE(this->mediaController); - SAFE_RELEASE(this->grabberController); + SAFE_RELEASE(this->mediaEventController); + SAFE_RELEASE(this->mediaController); + SAFE_RELEASE(this->grabberController); #if defined(_WIN32_WCE) - SAFE_RELEASE(this->colorConvertor565); + SAFE_RELEASE(this->colorConvertor565); #else #endif - SAFE_RELEASE(this->nullRendererFilter); - SAFE_RELEASE(this->sampleGrabberFilter); - SAFE_RELEASE(this->sourceFilter); + SAFE_RELEASE(this->nullRendererFilter); + SAFE_RELEASE(this->sampleGrabberFilter); + SAFE_RELEASE(this->sourceFilter); - SAFE_RELEASE(this->graphBuilder); - SAFE_RELEASE(this->captureGraphBuilder); + SAFE_RELEASE(this->graphBuilder); + SAFE_RELEASE(this->captureGraphBuilder); } HRESULT DSCaptureGraph::setSource(const std::string &devicePath) { - HRESULT hr = E_FAIL; + HRESULT hr = E_FAIL; - if (this->sourceFilter){ - this->graphBuilder->RemoveFilter(this->sourceFilter); - } + if (this->sourceFilter) { + this->graphBuilder->RemoveFilter(this->sourceFilter); + } - SAFE_RELEASE(this->streamConfiguration); - SAFE_RELEASE(this->sourceFilter); + SAFE_RELEASE(this->streamConfiguration); + SAFE_RELEASE(this->sourceFilter); - // Create the filter - this->deviceId = devicePath; - hr = createSourceFilter(&this->deviceId, &this->sourceFilter); + // Create the filter + this->deviceId = devicePath; + hr = createSourceFilter(&this->deviceId, &this->sourceFilter); - if (this->sourceFilter){ - // Gets the supported formats - this->supportedFormats.clear(); - getSupportedFormats(this->sourceFilter, &this->supportedFormats); + if (this->sourceFilter) { + // Gets the supported formats + this->supportedFormats.clear(); + getSupportedFormats(this->sourceFilter, &this->supportedFormats); - // Query for video stream config - hr = this->captureGraphBuilder->FindInterface( - &PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - this->sourceFilter, - IID_IAMStreamConfig, - reinterpret_cast<void**>(&this->streamConfiguration)); + // Query for video stream config + hr = this->captureGraphBuilder->FindInterface( + &PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, + this->sourceFilter, + IID_IAMStreamConfig, + reinterpret_cast<void**>(&this->streamConfiguration)); - hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_WEBCAM); - } + hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_WEBCAM); + } - return hr; + return hr; } HRESULT DSCaptureGraph::setParameters(DSCaptureFormat *format, int framerate) { - HRESULT hr = E_FAIL; - AM_MEDIA_TYPE *mediaType = NULL; + HRESULT hr = E_FAIL; + AM_MEDIA_TYPE *mediaType = NULL; - if (!this->streamConfiguration) goto bail; + if (!this->streamConfiguration) { + goto bail; + } - hr = this->streamConfiguration->GetFormat(&mediaType); - if (FAILED(hr)) goto bail; + hr = this->streamConfiguration->GetFormat(&mediaType); + if (FAILED(hr)) { + goto bail; + } - VIDEOINFOHEADER* vih = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat); - BITMAPINFOHEADER* bih = &vih->bmiHeader; + VIDEOINFOHEADER* vih = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat); + BITMAPINFOHEADER* bih = &vih->bmiHeader; - int w = format->getWidth(); - int h = format->getHeight(); + int w = format->getWidth(); + int h = format->getHeight(); - bool wN = (bih->biWidth<0); - bool hN = (bih->biHeight<0); + bool wN = (bih->biWidth<0); + bool hN = (bih->biHeight<0); - // DIBS are DWORD aligned - int data_size = h * ((w * bih->biBitCount + 31) / 32) * 4; + // DIBS are DWORD aligned + int data_size = h * ((w * bih->biBitCount + 31) / 32) * 4; - bih->biSize = sizeof(BITMAPINFOHEADER); - bih->biWidth = w*(wN?-1:1); - bih->biHeight = h*(hN?-1:1); - bih->biSizeImage = data_size; + bih->biSize = sizeof(BITMAPINFOHEADER); + bih->biWidth = w*(wN?-1:1); + bih->biHeight = h*(hN?-1:1); + bih->biSizeImage = data_size; - //vih->dwBitRate = framerate * data_size; - //vih->AvgTimePerFrame = SECONDS_TO_100NS(framerate); + //vih->dwBitRate = framerate * data_size; + //vih->AvgTimePerFrame = SECONDS_TO_100NS(framerate); - mediaType->cbFormat = sizeof(VIDEOINFOHEADER); - //mediaType->lSampleSize = data_size; - mediaType->subtype = format->getChroma(); + mediaType->cbFormat = sizeof(VIDEOINFOHEADER); + //mediaType->lSampleSize = data_size; + mediaType->subtype = format->getChroma(); - hr = this->streamConfiguration->SetFormat(mediaType); - if (FAILED(hr)) goto bail; + hr = this->streamConfiguration->SetFormat(mediaType); + if (FAILED(hr)) { + goto bail; + } #if defined(_WIN32_WCE) - hr = this->grabberController->SetFps((int) DS_SECONDS_FROM_100NS(vih->AvgTimePerFrame)/*format->getFramerate()*/, framerate); - if (FAILED(hr)) goto bail; - hr = this->grabberController->SetSize(w,h); + hr = this->grabberController->SetFps((int) DS_SECONDS_FROM_100NS(vih->AvgTimePerFrame)/*format->getFramerate()*/, framerate); + if (FAILED(hr)) { + goto bail; + } + hr = this->grabberController->SetSize(w,h); #else - // Set fps using tdshow filter - hr = this->frameRateFilter->SetFps((int) ((float)vih->AvgTimePerFrame/10000.f)/*format->getFramerate()*/, framerate); + // Set fps using tdshow filter + hr = this->frameRateFilter->SetFps((int) ((float)vih->AvgTimePerFrame/10000.f)/*format->getFramerate()*/, framerate); #endif - if (FAILED(hr)) goto bail; + if (FAILED(hr)) { + goto bail; + } - this->captureFormat = format; + this->captureFormat = format; bail: - DeleteMediaType(mediaType); + DeleteMediaType(mediaType); - return hr; + return hr; } #if defined(_WIN32_WCE) @@ -178,259 +188,314 @@ bail: HRESULT DSCaptureGraph::connect() { - HRESULT hr; + HRESULT hr; - if (!this->sourceFilter){ - TSK_DEBUG_ERROR("Invalid source filter"); - return E_FAIL; - } + if (!this->sourceFilter) { + TSK_DEBUG_ERROR("Invalid source filter"); + return E_FAIL; + } - if (!this->captureFormat){ - TSK_DEBUG_ERROR("Invalid capture format"); - return E_FAIL; - } + if (!this->captureFormat) { + TSK_DEBUG_ERROR("Invalid capture format"); + return E_FAIL; + } - if (!this->graphBuilder){ - TSK_DEBUG_ERROR("Invalid grash builder"); - return E_FAIL; - } + if (!this->graphBuilder) { + TSK_DEBUG_ERROR("Invalid grash builder"); + return E_FAIL; + } - if (this->captureFormat->isRGB()) - { + if (this->captureFormat->isRGB()) { #if defined(_WIN32_WCE) - hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565) ; if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter) ; if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } + hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565) ; + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter) ; + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } #else - hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } + hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } #endif - } - else - { + } + else { #if defined(_WIN32_WCE) - hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565) ; if(FAILED(hr))return hr; - hr = ConnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter) ; if(FAILED(hr))return hr; - hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr))return hr; + hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565) ; + if(FAILED(hr)) { + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter) ; + if(FAILED(hr)) { + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + return hr; + } #else - // No convertor needed - // AVI Decompressor Filter is automatically by the Filter Graph Manager when needed - hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } + // No convertor needed + // AVI Decompressor Filter is automatically by the Filter Graph Manager when needed + hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } #endif - } + } - return hr; + return hr; } HRESULT DSCaptureGraph::disconnect() { - HRESULT hr; + HRESULT hr; - if (!this->sourceFilter) { - return E_FAIL; - } + if (!this->sourceFilter) { + return E_FAIL; + } - if (!this->captureFormat) { - return E_FAIL; - } + if (!this->captureFormat) { + return E_FAIL; + } - if (this->captureFormat->isRGB()) - { + if (this->captureFormat->isRGB()) { #if defined(_WIN32_WCE) - hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565); - hr = DisconnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter); - hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565); + hr = DisconnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter); + hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); #else - hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); - hr = DisconnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); - hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); + hr = DisconnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); + hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); #endif - } - else - { + } + else { #if defined(_WIN32_WCE) - hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565); if(FAILED(hr))return hr; - hr = DisconnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter); if(FAILED(hr))return hr; - hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr))return hr; + hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorConvertor565); + if(FAILED(hr)) { + return hr; + } + hr = DisconnectFilters(this->graphBuilder, this->colorConvertor565, this->sampleGrabberFilter); + if(FAILED(hr)) { + return hr; + } + hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + return hr; + } #else - hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); - hr = DisconnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); - hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->frameRateFilter); + hr = DisconnectFilters(this->graphBuilder, this->frameRateFilter, this->sampleGrabberFilter); + hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); #endif - } + } - return hr; + return hr; } HRESULT DSCaptureGraph::start() { - HRESULT hr; - - if (isRunning() && !isPaused()) { - return S_OK; - } - - //this->mediaController->Stop(); - - hr = this->mediaController ? this->mediaController->Run() : E_POINTER; - /*if (hr == S_FALSE) - { - cerr << "DSCaptureGraph::mediaController->Start() has failed with " << hr << ". Waiting for transition." << endl; - FILTER_STATE pfs; - hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); - hr = this->mediaController->Run(); - }*/ - - if (!SUCCEEDED(hr)) - { + HRESULT hr; + + if (isRunning() && !isPaused()) { + return S_OK; + } + + //this->mediaController->Stop(); + + hr = this->mediaController ? this->mediaController->Run() : E_POINTER; + /*if (hr == S_FALSE) + { + cerr << "DSCaptureGraph::mediaController->Start() has failed with " << hr << ". Waiting for transition." << endl; + FILTER_STATE pfs; + hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); + hr = this->mediaController->Run(); + }*/ + + if (!SUCCEEDED(hr)) { #if defined(_WIN32_WCE) - MessageBox(NULL, _T("Starting DirectShow Graph Failed"), _T("Failure"), MB_OK); - //assert(1==15); + MessageBox(NULL, _T("Starting DirectShow Graph Failed"), _T("Failure"), MB_OK); + //assert(1==15); #endif - TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Run() has failed with %ld", hr); - return hr; - } - this->running = true; - return hr; + TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Run() has failed with %ld", hr); + return hr; + } + this->running = true; + return hr; } HRESULT DSCaptureGraph::pause() { - HRESULT hr = S_OK; - if (isRunning()) { - hr = this->mediaController->Pause(); - if (SUCCEEDED(hr)) { - this->paused = TRUE; - } - } - return hr; + HRESULT hr = S_OK; + if (isRunning()) { + hr = this->mediaController->Pause(); + if (SUCCEEDED(hr)) { + this->paused = TRUE; + } + } + return hr; } HRESULT DSCaptureGraph::stop() { - HRESULT hr; + HRESULT hr; #if 0 // Must not - hr = this->mediaController->Pause(); - if (hr == S_FALSE) - { - TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Pause() has failed with %ld. Waiting for transition.", hr); - FILTER_STATE pfs; - hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); - } + hr = this->mediaController->Pause(); + if (hr == S_FALSE) { + TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Pause() has failed with %ld. Waiting for transition.", hr); + FILTER_STATE pfs; + hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); + } #endif - hr = this->mediaController->Stop(); - if (!SUCCEEDED(hr)) - { - TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Stop() has failed with %ld", hr); - } - this->running = false; - this->paused = false; - return hr; + hr = this->mediaController->Stop(); + if (!SUCCEEDED(hr)) { + TSK_DEBUG_ERROR("DSCaptureGraph::mediaController->Stop() has failed with %ld", hr); + } + this->running = false; + this->paused = false; + return hr; } bool DSCaptureGraph::isRunning() { - return this->running; + return this->running; } bool DSCaptureGraph::isPaused() { - return this->paused; + return this->paused; } HRESULT DSCaptureGraph::getConnectedMediaType(AM_MEDIA_TYPE *mediaType) { #if defined(_WIN32_WCE) - memmove(mediaType, &this->grabberController->GetMediaType(), sizeof(AM_MEDIA_TYPE)); - return S_OK; + memmove(mediaType, &this->grabberController->GetMediaType(), sizeof(AM_MEDIA_TYPE)); + return S_OK; #else - return this->grabberController->GetConnectedMediaType(mediaType); + return this->grabberController->GetConnectedMediaType(mediaType); #endif } HRESULT DSCaptureGraph::createCaptureGraph() { - HRESULT hr; + HRESULT hr; #if defined(_WIN32_WCE) - // Create capture graph builder - CHECK_HR(hr = COCREATE(CLSID_CaptureGraphBuilder, IID_ICaptureGraphBuilder2, this->captureGraphBuilder)); - CHECK_HR(hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder)); - CHECK_HR(hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder)); - - // Create filters - LPUNKNOWN pUnk1 = NULL, pUnk2 = NULL; - CHECK_HR(hr = COCREATE(CLSID_Colour, IID_IBaseFilter, this->colorConvertor565)); - this->sampleGrabberFilter = new DSSampleGrabber(FITLER_SAMPLE_GRABBER, pUnk1, &hr); CHECK_HR(hr); - this->nullRendererFilter = new DSNullFilter(/*FILTER_NULL_RENDERER,*/ pUnk2, &hr); CHECK_HR(hr); - this->grabberController = (DSSampleGrabber*)(this->sampleGrabberFilter); if (!this->grabberController) CHECK_HR(E_FAIL); - - // Add Filters - CHECK_HR(hr = this->graphBuilder->AddFilter(this->colorConvertor565, FILTER_COLOR_CONVERTOR_565)); - CHECK_HR(hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER)); - CHECK_HR(hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER)); - - // Find media control - CHECK_HR(hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController)); - - // Set callback - CHECK_HR(hr = this->grabberController->SetCallback(this->grabberCallback)); + // Create capture graph builder + CHECK_HR(hr = COCREATE(CLSID_CaptureGraphBuilder, IID_ICaptureGraphBuilder2, this->captureGraphBuilder)); + CHECK_HR(hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder)); + CHECK_HR(hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder)); + + // Create filters + LPUNKNOWN pUnk1 = NULL, pUnk2 = NULL; + CHECK_HR(hr = COCREATE(CLSID_Colour, IID_IBaseFilter, this->colorConvertor565)); + this->sampleGrabberFilter = new DSSampleGrabber(FITLER_SAMPLE_GRABBER, pUnk1, &hr); + CHECK_HR(hr); + this->nullRendererFilter = new DSNullFilter(/*FILTER_NULL_RENDERER,*/ pUnk2, &hr); + CHECK_HR(hr); + this->grabberController = (DSSampleGrabber*)(this->sampleGrabberFilter); + if (!this->grabberController) { + CHECK_HR(E_FAIL); + } + + // Add Filters + CHECK_HR(hr = this->graphBuilder->AddFilter(this->colorConvertor565, FILTER_COLOR_CONVERTOR_565)); + CHECK_HR(hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER)); + CHECK_HR(hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER)); + + // Find media control + CHECK_HR(hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController)); + + // Set callback + CHECK_HR(hr = this->grabberController->SetCallback(this->grabberCallback)); #else - // Create capture graph builder - CHECK_HR(hr = COCREATE(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2, this->captureGraphBuilder)); + // Create capture graph builder + CHECK_HR(hr = COCREATE(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2, this->captureGraphBuilder)); - // Create the graph builder - CHECK_HR(hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder)); + // Create the graph builder + CHECK_HR(hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder)); - // Initialize the Capture Graph Builder. - CHECK_HR(hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder)); + // Initialize the Capture Graph Builder. + CHECK_HR(hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder)); - // Create the sample grabber filter - CHECK_HR(hr = COCREATE(CLSID_SampleGrabber, IID_IBaseFilter, this->sampleGrabberFilter)); + // Create the sample grabber filter + CHECK_HR(hr = COCREATE(CLSID_SampleGrabber, IID_IBaseFilter, this->sampleGrabberFilter)); - // Create tdshow filter - LPUNKNOWN pUnk = NULL; - this->frameRateFilter = new DSFrameRateFilter(FILTER_FRAMERATE, pUnk, &hr); CHECK_HR(hr); - if (!this->frameRateFilter == NULL) CHECK_HR(E_FAIL); + // Create tdshow filter + LPUNKNOWN pUnk = NULL; + this->frameRateFilter = new DSFrameRateFilter(FILTER_FRAMERATE, pUnk, &hr); + CHECK_HR(hr); + if (!this->frameRateFilter == NULL) { + CHECK_HR(E_FAIL); + } - // Create the NULL renderer - CHECK_HR(hr = COCREATE(CLSID_NullRenderer, IID_IBaseFilter, this->nullRendererFilter)); + // Create the NULL renderer + CHECK_HR(hr = COCREATE(CLSID_NullRenderer, IID_IBaseFilter, this->nullRendererFilter)); - // Add sample grabber to the graph - CHECK_HR(hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER)); + // Add sample grabber to the graph + CHECK_HR(hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER)); - // Add null renderer to the graph - CHECK_HR(hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER)); + // Add null renderer to the graph + CHECK_HR(hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER)); - // Add tdshow filter - CHECK_HR(hr = this->graphBuilder->AddFilter(this->frameRateFilter, FILTER_FRAMERATE)); + // Add tdshow filter + CHECK_HR(hr = this->graphBuilder->AddFilter(this->frameRateFilter, FILTER_FRAMERATE)); - // Find media control - CHECK_HR(hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController)); + // Find media control + CHECK_HR(hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController)); - // Create the sample grabber - CHECK_HR(hr = QUERY(this->sampleGrabberFilter, IID_ISampleGrabber, this->grabberController)); + // Create the sample grabber + CHECK_HR(hr = QUERY(this->sampleGrabberFilter, IID_ISampleGrabber, this->grabberController)); - // Set the sample grabber media type (RGB24) - // TODO : CHECK - AM_MEDIA_TYPE mt; - ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - mt.subtype = MEDIASUBTYPE_RGB24; - mt.formattype = FORMAT_VideoInfo; + // Set the sample grabber media type (RGB24) + // TODO : CHECK + AM_MEDIA_TYPE mt; + ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Video; + mt.subtype = MEDIASUBTYPE_RGB24; + mt.formattype = FORMAT_VideoInfo; - CHECK_HR(hr = this->grabberController->SetMediaType(&mt)); + CHECK_HR(hr = this->grabberController->SetMediaType(&mt)); - // Set sample grabber media type - this->grabberController->SetOneShot(FALSE); - this->grabberController->SetBufferSamples(FALSE); + // Set sample grabber media type + this->grabberController->SetOneShot(FALSE); + this->grabberController->SetBufferSamples(FALSE); - CHECK_HR(hr = this->grabberController->SetCallback(this->grabberCallback, 1)); + CHECK_HR(hr = this->grabberController->SetCallback(this->grabberCallback, 1)); #endif bail: - return hr; + return hr; }
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/DSCaptureGraph.h b/plugins/pluginDirectShow/internals/DSCaptureGraph.h index 6bf8862..7c9b674 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureGraph.h +++ b/plugins/pluginDirectShow/internals/DSCaptureGraph.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -37,70 +37,74 @@ class DSCaptureGraph : public DSBaseCaptureGraph { public: #ifdef _WIN32_WCE - DSCaptureGraph(DSISampleGrabberCB* callback, HRESULT *hr); + DSCaptureGraph(DSISampleGrabberCB* callback, HRESULT *hr); #else - DSCaptureGraph(ISampleGrabberCB* callback, HRESULT *hr); + DSCaptureGraph(ISampleGrabberCB* callback, HRESULT *hr); #endif - virtual ~DSCaptureGraph(); + virtual ~DSCaptureGraph(); - std::vector<DSCaptureFormat> *getFormats() { return &this->supportedFormats; }; + std::vector<DSCaptureFormat> *getFormats() { + return &this->supportedFormats; + }; - HRESULT setSource(const std::string &devicePath); - HRESULT setParameters(DSCaptureFormat *format, int framerate); + HRESULT setSource(const std::string &devicePath); + HRESULT setParameters(DSCaptureFormat *format, int framerate); - HRESULT connect(); - HRESULT disconnect(); + HRESULT connect(); + HRESULT disconnect(); - HRESULT start(); - HRESULT stop(); - HRESULT pause(); - bool isRunning(); - bool isPaused(); + HRESULT start(); + HRESULT stop(); + HRESULT pause(); + bool isRunning(); + bool isPaused(); - std::string getDeviceId() const { return this->deviceId; }; + std::string getDeviceId() const { + return this->deviceId; + }; - HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); + HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); private: - HRESULT createCaptureGraph(); + HRESULT createCaptureGraph(); private: #ifdef _WIN32_WCE - DSISampleGrabberCB *grabberCallback; + DSISampleGrabberCB *grabberCallback; #else - ISampleGrabberCB *grabberCallback; + ISampleGrabberCB *grabberCallback; #endif - ICaptureGraphBuilder2 *captureGraphBuilder; - IGraphBuilder *graphBuilder; + ICaptureGraphBuilder2 *captureGraphBuilder; + IGraphBuilder *graphBuilder; + + IBaseFilter *sourceFilter; + IBaseFilter *nullRendererFilter; + IBaseFilter *sampleGrabberFilter; - IBaseFilter *sourceFilter; - IBaseFilter *nullRendererFilter; - IBaseFilter *sampleGrabberFilter; - #ifdef _WIN32_WCE - IBaseFilter *colorConvertor565; //http://msdn.microsoft.com/en-us/library/aa926076.aspx + IBaseFilter *colorConvertor565; //http://msdn.microsoft.com/en-us/library/aa926076.aspx #else - DSFrameRateFilter *frameRateFilter; + DSFrameRateFilter *frameRateFilter; #endif #ifdef _WIN32_WCE - DSSampleGrabber *grabberController; + DSSampleGrabber *grabberController; #else - ISampleGrabber *grabberController; + ISampleGrabber *grabberController; #endif - IMediaControl *mediaController; - IMediaEventEx *mediaEventController; + IMediaControl *mediaController; + IMediaEventEx *mediaEventController; - IAMStreamConfig *streamConfiguration; + IAMStreamConfig *streamConfiguration; - std::vector<DSCaptureFormat> supportedFormats; - DSCaptureFormat *captureFormat; + std::vector<DSCaptureFormat> supportedFormats; + DSCaptureFormat *captureFormat; - bool running; - bool paused; - std::string deviceId; + bool running; + bool paused; + std::string deviceId; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSCaptureUtils.cxx b/plugins/pluginDirectShow/internals/DSCaptureUtils.cxx index d95f996..6c99476 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureUtils.cxx +++ b/plugins/pluginDirectShow/internals/DSCaptureUtils.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -38,340 +38,367 @@ HRESULT enumerateCaptureDevices(const std::string &prefix, std::vector<VideoGrabberName> *names) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; #ifdef _WIN32_WCE - // FIXME: use FindNextDevice to query all devices - HANDLE handle = NULL; - DEVMGR_DEVICE_INFORMATION di; - - TCHAR pwzName[MAX_PATH]; memset(pwzName,NULL,MAX_PATH); - - GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, - 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 }; // http://msdn.microsoft.com/en-us/library/aa918757.aspx - - di.dwSize = sizeof(di); - - for( int i=0; ; i++) - { - if(0 == i) - { /* 1st time */ - handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); - if(!handle || !di.hDevice) - { - hr = ( HRESULT_FROM_WIN32( GetLastError() )); - goto bail; - } - } - else if(handle) - { /* 2nd or 3rd time */ - BOOL ret = FindNextDevice(handle, &di); - if(!ret || !di.hDevice) - { - /* No 2nd or 3rd camera ==> do not return error*/ - goto bail; - } - } - else assert(0); - - StringCchCopy( pwzName, MAX_PATH, di.szDeviceName ); - - /* from LPWSTR to LPSTR */ - char mbstr_name[MAX_PATH]; memset(mbstr_name,NULL,MAX_PATH); - wcstombs(mbstr_name, pwzName, MAX_PATH); - - VideoGrabberName grabberName(std::string((const char*)mbstr_name), std::string((const char*)mbstr_name)); - names->push_back(grabberName); - } - + // FIXME: use FindNextDevice to query all devices + HANDLE handle = NULL; + DEVMGR_DEVICE_INFORMATION di; + + TCHAR pwzName[MAX_PATH]; + memset(pwzName,NULL,MAX_PATH); + + GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, + 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 + }; // http://msdn.microsoft.com/en-us/library/aa918757.aspx + + di.dwSize = sizeof(di); + + for( int i=0; ; i++) { + if(0 == i) { + /* 1st time */ + handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); + if(!handle || !di.hDevice) { + hr = ( HRESULT_FROM_WIN32( GetLastError() )); + goto bail; + } + } + else if(handle) { + /* 2nd or 3rd time */ + BOOL ret = FindNextDevice(handle, &di); + if(!ret || !di.hDevice) { + /* No 2nd or 3rd camera ==> do not return error*/ + goto bail; + } + } + else { + assert(0); + } + + StringCchCopy( pwzName, MAX_PATH, di.szDeviceName ); + + /* from LPWSTR to LPSTR */ + char mbstr_name[MAX_PATH]; + memset(mbstr_name,NULL,MAX_PATH); + wcstombs(mbstr_name, pwzName, MAX_PATH); + + VideoGrabberName grabberName(std::string((const char*)mbstr_name), std::string((const char*)mbstr_name)); + names->push_back(grabberName); + } + bail: - /* close */ - if(handle) FindClose( handle ); - + /* close */ + if(handle) { + FindClose( handle ); + } + #else - ICreateDevEnum *deviceEnum; - IEnumMoniker *enumerator; - IMoniker *moniker; - - // Create the System Device Enumerator - hr = COCREATE(CLSID_SystemDeviceEnum, IID_ICreateDevEnum, deviceEnum); - if (FAILED(hr)) goto bail; - - // Ask for a device enumerator - hr = deviceEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumerator, INCLUDE_CATEGORY_FLAG); - if (FAILED(hr)) goto bail; - - // hr = S_FALSE and enumerator is NULL if there is no device to enumerate - if (!enumerator) goto bail; - - USES_CONVERSION; - - while (enumerator->Next(1, &moniker, NULL) == S_OK) - { - // Get the properties bag for each device - IPropertyBag *propBag; - hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&propBag)); - if (FAILED(hr)) - { - SAFE_RELEASE(moniker); - continue; - } - - std::string name; - std::string description; - - VARIANT varName; - VariantInit(&varName); - VARIANT varDescription; - VariantInit(&varDescription); - - // Find the device path (uniqueness is guaranteed) - hr = propBag->Read(L"DevicePath", &varName, 0); - if (SUCCEEDED(hr)) - { - if (prefix != "") name = prefix + ":"; - name = name + std::string(W2A(varName.bstrVal)); - } - - // Find friendly name or the description - hr = propBag->Read(L"FriendlyName", &varDescription, 0); - if (SUCCEEDED(hr)) - { - description = std::string(W2A(varDescription.bstrVal)); - } - else - { - hr = propBag->Read(L"Description", &varDescription, 0); - if (SUCCEEDED(hr)) description = std::string(W2A(varDescription.bstrVal)); - } - - hr = VariantClear(&varName); - hr = VariantClear(&varDescription); - - SAFE_RELEASE(propBag); - SAFE_RELEASE(moniker); - - // Add it to the list - if (name != "") - { - VideoGrabberName grabberName(name, description); - names->push_back(grabberName); - } - } + ICreateDevEnum *deviceEnum; + IEnumMoniker *enumerator; + IMoniker *moniker; + + // Create the System Device Enumerator + hr = COCREATE(CLSID_SystemDeviceEnum, IID_ICreateDevEnum, deviceEnum); + if (FAILED(hr)) { + goto bail; + } + + // Ask for a device enumerator + hr = deviceEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumerator, INCLUDE_CATEGORY_FLAG); + if (FAILED(hr)) { + goto bail; + } + + // hr = S_FALSE and enumerator is NULL if there is no device to enumerate + if (!enumerator) { + goto bail; + } + + USES_CONVERSION; + + while (enumerator->Next(1, &moniker, NULL) == S_OK) { + // Get the properties bag for each device + IPropertyBag *propBag; + hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&propBag)); + if (FAILED(hr)) { + SAFE_RELEASE(moniker); + continue; + } + + std::string name; + std::string description; + + VARIANT varName; + VariantInit(&varName); + VARIANT varDescription; + VariantInit(&varDescription); + + // Find the device path (uniqueness is guaranteed) + hr = propBag->Read(L"DevicePath", &varName, 0); + if (SUCCEEDED(hr)) { + if (prefix != "") { + name = prefix + ":"; + } + name = name + std::string(W2A(varName.bstrVal)); + } + + // Find friendly name or the description + hr = propBag->Read(L"FriendlyName", &varDescription, 0); + if (SUCCEEDED(hr)) { + description = std::string(W2A(varDescription.bstrVal)); + } + else { + hr = propBag->Read(L"Description", &varDescription, 0); + if (SUCCEEDED(hr)) { + description = std::string(W2A(varDescription.bstrVal)); + } + } + + hr = VariantClear(&varName); + hr = VariantClear(&varDescription); + + SAFE_RELEASE(propBag); + SAFE_RELEASE(moniker); + + // Add it to the list + if (name != "") { + VideoGrabberName grabberName(name, description); + names->push_back(grabberName); + } + } bail: - SAFE_RELEASE(enumerator); - SAFE_RELEASE(deviceEnum); + SAFE_RELEASE(enumerator); + SAFE_RELEASE(deviceEnum); #endif - return hr; + return hr; } HRESULT createSourceFilter(std::string *devicePath, IBaseFilter **sourceFilter) { - HRESULT hr; - - IEnumMoniker *enumerator = NULL; - IMoniker *moniker = NULL; - bool found = false; + HRESULT hr; - // Set sourceFilter to null - SAFE_RELEASE((*sourceFilter)); + IEnumMoniker *enumerator = NULL; + IMoniker *moniker = NULL; + bool found = false; + + // Set sourceFilter to null + SAFE_RELEASE((*sourceFilter)); #if defined( _WIN32_WCE) - CPropertyBag pBag; - HANDLE handle = NULL; - DEVMGR_DEVICE_INFORMATION di; - TCHAR pwzName[MAX_PATH]; - CComVariant varCamName; - IPersistPropertyBag *propBag = NULL; - GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, - 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 }; // http://msdn.microsoft.com/en-us/library/aa918757.aspx - - di.dwSize = sizeof(di); - - for( int i=0; ; i++) - { - if(0 == i) - { /* 1st time */ - handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); - if(!handle || !di.hDevice) - { - hr = ( HRESULT_FROM_WIN32( GetLastError() )); - goto bail; - } - } - else if(handle) - { /* 2nd or 3rd time */ - BOOL ret = FindNextDevice(handle, &di); - if(!ret || !di.hDevice) - { - /* No 2nd or 3rd camera ==> do not return error*/ - goto bail; - } - } - else assert(0); - - StringCchCopy( pwzName, MAX_PATH, di.szDeviceName ); - - /* from LPWSTR to LPSTR */ - char mbstr_name[MAX_PATH]; - memset(mbstr_name,NULL,MAX_PATH); - wcstombs(mbstr_name, pwzName, MAX_PATH); - - if((std::string((const char*)mbstr_name) == (*devicePath)) || ("0" == (*devicePath))) - { - varCamName = pwzName; - if( varCamName.vt != VT_BSTR ) - { - hr = E_OUTOFMEMORY; - goto bail; - } - - // Create Source filter - hr = COCREATE(CLSID_VideoCapture, IID_IBaseFilter, *sourceFilter); - if(FAILED(hr)) goto bail; - - // Query PropertyBag - hr = QUERY((*sourceFilter), IID_IPersistPropertyBag, propBag); - if(FAILED(hr)) goto bail; - - hr = pBag.Write( L"VCapName", &varCamName ); - if(FAILED(hr)) goto bail; - - hr = propBag->Load( &pBag, NULL ); - if(FAILED(hr)) goto bail; - } - } + CPropertyBag pBag; + HANDLE handle = NULL; + DEVMGR_DEVICE_INFORMATION di; + TCHAR pwzName[MAX_PATH]; + CComVariant varCamName; + IPersistPropertyBag *propBag = NULL; + GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, + 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 + }; // http://msdn.microsoft.com/en-us/library/aa918757.aspx + + di.dwSize = sizeof(di); + + for( int i=0; ; i++) { + if(0 == i) { + /* 1st time */ + handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); + if(!handle || !di.hDevice) { + hr = ( HRESULT_FROM_WIN32( GetLastError() )); + goto bail; + } + } + else if(handle) { + /* 2nd or 3rd time */ + BOOL ret = FindNextDevice(handle, &di); + if(!ret || !di.hDevice) { + /* No 2nd or 3rd camera ==> do not return error*/ + goto bail; + } + } + else { + assert(0); + } + + StringCchCopy( pwzName, MAX_PATH, di.szDeviceName ); + + /* from LPWSTR to LPSTR */ + char mbstr_name[MAX_PATH]; + memset(mbstr_name,NULL,MAX_PATH); + wcstombs(mbstr_name, pwzName, MAX_PATH); + + if((std::string((const char*)mbstr_name) == (*devicePath)) || ("0" == (*devicePath))) { + varCamName = pwzName; + if( varCamName.vt != VT_BSTR ) { + hr = E_OUTOFMEMORY; + goto bail; + } + + // Create Source filter + hr = COCREATE(CLSID_VideoCapture, IID_IBaseFilter, *sourceFilter); + if(FAILED(hr)) { + goto bail; + } + + // Query PropertyBag + hr = QUERY((*sourceFilter), IID_IPersistPropertyBag, propBag); + if(FAILED(hr)) { + goto bail; + } + + hr = pBag.Write( L"VCapName", &varCamName ); + if(FAILED(hr)) { + goto bail; + } + + hr = propBag->Load( &pBag, NULL ); + if(FAILED(hr)) { + goto bail; + } + } + } #else - ICreateDevEnum *deviceEnum = NULL; - IPropertyBag *propBag = NULL; - - // Create the System Device Enumerator - hr = COCREATE(CLSID_SystemDeviceEnum, IID_ICreateDevEnum, deviceEnum); - if (FAILED(hr)){ - goto bail; - } - - // Ask for a device enumerator - hr = deviceEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumerator, INCLUDE_CATEGORY_FLAG); - if(FAILED(hr)){ - goto bail; - } - - // hr = S_FALSE and enumerator is NULL if there is no device to enumerate - if(!enumerator){ - goto bail; - } - - USES_CONVERSION; - - while (!found && (enumerator->Next(1, &moniker, NULL) == S_OK)){ - // Get the properties bag for each device - hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&propBag)); - if (FAILED(hr)){ - SAFE_RELEASE(moniker); - continue; - } - - std::string name; - - VARIANT varName; - VariantInit(&varName); - - // Find the device path (uniqueness is guaranteed) - hr = propBag->Read(L"DevicePath", &varName, 0); - if (SUCCEEDED(hr)) name = std::string(W2A(varName.bstrVal)); - - // Check for device path - // "Null" means first found - if ((name == (*devicePath)) || - ("Null" == (*devicePath))) - { - hr = moniker->BindToObject(0, 0, IID_IBaseFilter, reinterpret_cast<void**>(&(*sourceFilter))); - if (SUCCEEDED(hr)){ - (*devicePath) = name; - found = true; - } - } - - hr = VariantClear(&varName); - - SAFE_RELEASE(propBag); - SAFE_RELEASE(moniker); - } + ICreateDevEnum *deviceEnum = NULL; + IPropertyBag *propBag = NULL; + + // Create the System Device Enumerator + hr = COCREATE(CLSID_SystemDeviceEnum, IID_ICreateDevEnum, deviceEnum); + if (FAILED(hr)) { + goto bail; + } + + // Ask for a device enumerator + hr = deviceEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumerator, INCLUDE_CATEGORY_FLAG); + if(FAILED(hr)) { + goto bail; + } + + // hr = S_FALSE and enumerator is NULL if there is no device to enumerate + if(!enumerator) { + goto bail; + } + + USES_CONVERSION; + + while (!found && (enumerator->Next(1, &moniker, NULL) == S_OK)) { + // Get the properties bag for each device + hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast<void**>(&propBag)); + if (FAILED(hr)) { + SAFE_RELEASE(moniker); + continue; + } + + std::string name; + + VARIANT varName; + VariantInit(&varName); + + // Find the device path (uniqueness is guaranteed) + hr = propBag->Read(L"DevicePath", &varName, 0); + if (SUCCEEDED(hr)) { + name = std::string(W2A(varName.bstrVal)); + } + + // Check for device path + // "Null" means first found + if ((name == (*devicePath)) || + ("Null" == (*devicePath))) { + hr = moniker->BindToObject(0, 0, IID_IBaseFilter, reinterpret_cast<void**>(&(*sourceFilter))); + if (SUCCEEDED(hr)) { + (*devicePath) = name; + found = true; + } + } + + hr = VariantClear(&varName); + + SAFE_RELEASE(propBag); + SAFE_RELEASE(moniker); + } #endif bail: #ifdef _WIN32_WCE - if(handle) FindClose(handle); + if(handle) { + FindClose(handle); + } #else - SAFE_RELEASE(deviceEnum); + SAFE_RELEASE(deviceEnum); #endif - SAFE_RELEASE(moniker); - SAFE_RELEASE(enumerator); - SAFE_RELEASE(propBag); + SAFE_RELEASE(moniker); + SAFE_RELEASE(enumerator); + SAFE_RELEASE(propBag); - return hr; + return hr; } HRESULT getSupportedFormats(IBaseFilter *sourceFilter, std::vector<DSCaptureFormat> *formats) { - HRESULT hr = E_FAIL; - IPin *pinOut = NULL; - IAMStreamConfig *streamConfig = NULL; - AM_MEDIA_TYPE *mediaType = NULL; - int count, size; - - // Check source filter pointer - if (!sourceFilter) goto bail; - - pinOut = GetPin(sourceFilter, PINDIR_OUTPUT); - if(!pinOut) goto bail; - - // Retrieve the stream config interface - hr = QUERY(pinOut, IID_IAMStreamConfig, streamConfig); - if (FAILED(hr)) goto bail; - - // Get the number of capabilities - hr = streamConfig->GetNumberOfCapabilities(&count, &size); - if (FAILED(hr)) goto bail; - - hr = streamConfig->GetFormat(&mediaType); - if (FAILED(hr)) goto bail; - - // Iterate through the formats - for (int i = 0; i < count; i++){ - VIDEO_STREAM_CONFIG_CAPS streamConfigCaps; - - hr = streamConfig->GetStreamCaps(i, &mediaType, reinterpret_cast<BYTE*>(&streamConfigCaps)); - - if (FAILED(hr)){ - TSK_DEBUG_ERROR("Failed to get Stream caps"); - break; - } - - if (streamConfigCaps.guid == FORMAT_VideoInfo){ - VIDEOINFOHEADER* vih = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat); - BITMAPINFOHEADER* bih = &vih->bmiHeader; - - int width = abs(bih->biWidth); - int height = abs(bih->biHeight); - int fps = (int) ((float)(vih->AvgTimePerFrame)/10000.f); - GUID chroma = mediaType->subtype; - - // Add format to the list - DSCaptureFormat format(width, height, fps, chroma); - formats->push_back(format); - } - - DeleteMediaType(mediaType); - } + HRESULT hr = E_FAIL; + IPin *pinOut = NULL; + IAMStreamConfig *streamConfig = NULL; + AM_MEDIA_TYPE *mediaType = NULL; + int count, size; + + // Check source filter pointer + if (!sourceFilter) { + goto bail; + } + + pinOut = GetPin(sourceFilter, PINDIR_OUTPUT); + if(!pinOut) { + goto bail; + } + + // Retrieve the stream config interface + hr = QUERY(pinOut, IID_IAMStreamConfig, streamConfig); + if (FAILED(hr)) { + goto bail; + } + + // Get the number of capabilities + hr = streamConfig->GetNumberOfCapabilities(&count, &size); + if (FAILED(hr)) { + goto bail; + } + + hr = streamConfig->GetFormat(&mediaType); + if (FAILED(hr)) { + goto bail; + } + + // Iterate through the formats + for (int i = 0; i < count; i++) { + VIDEO_STREAM_CONFIG_CAPS streamConfigCaps; + + hr = streamConfig->GetStreamCaps(i, &mediaType, reinterpret_cast<BYTE*>(&streamConfigCaps)); + + if (FAILED(hr)) { + TSK_DEBUG_ERROR("Failed to get Stream caps"); + break; + } + + if (streamConfigCaps.guid == FORMAT_VideoInfo) { + VIDEOINFOHEADER* vih = reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat); + BITMAPINFOHEADER* bih = &vih->bmiHeader; + + int width = abs(bih->biWidth); + int height = abs(bih->biHeight); + int fps = (int) ((float)(vih->AvgTimePerFrame)/10000.f); + GUID chroma = mediaType->subtype; + + // Add format to the list + DSCaptureFormat format(width, height, fps, chroma); + formats->push_back(format); + } + + DeleteMediaType(mediaType); + } bail: - SAFE_RELEASE(streamConfig); - SAFE_RELEASE(pinOut); + SAFE_RELEASE(streamConfig); + SAFE_RELEASE(pinOut); - return hr; + return hr; } diff --git a/plugins/pluginDirectShow/internals/DSCaptureUtils.h b/plugins/pluginDirectShow/internals/DSCaptureUtils.h index 7d99ed2..f7d6b60 100755 --- a/plugins/pluginDirectShow/internals/DSCaptureUtils.h +++ b/plugins/pluginDirectShow/internals/DSCaptureUtils.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ diff --git a/plugins/pluginDirectShow/internals/DSDibHelper.cxx b/plugins/pluginDirectShow/internals/DSDibHelper.cxx index b7f40d5..3b02ae2 100755 --- a/plugins/pluginDirectShow/internals/DSDibHelper.cxx +++ b/plugins/pluginDirectShow/internals/DSDibHelper.cxx @@ -22,11 +22,12 @@ HBITMAP CopyScreenToBitmap(LPRECT lpRect, BYTE *pData, BITMAPINFO *pHeader) int xScrn, yScrn; // screen resolution // check for an empty rectangle - if (IsRectEmpty(lpRect)) - return NULL; + if (IsRectEmpty(lpRect)) { + return NULL; + } // create a DC for the screen and create - // a memory DC compatible to screen DC + // a memory DC compatible to screen DC hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); hMemDC = CreateCompatibleDC(hScrDC); @@ -41,14 +42,18 @@ HBITMAP CopyScreenToBitmap(LPRECT lpRect, BYTE *pData, BITMAPINFO *pHeader) yScrn = GetDeviceCaps(hScrDC, VERTRES); //make sure bitmap rectangle is visible - if (nX < 0) + if (nX < 0) { nX = 0; - if (nY < 0) + } + if (nY < 0) { nY = 0; - if (nX2 > xScrn) + } + if (nX2 > xScrn) { nX2 = xScrn; - if (nY2 > yScrn) + } + if (nY2 > yScrn) { nY2 = yScrn; + } nWidth = nX2 - nX; nHeight = nY2 - nY; @@ -63,7 +68,7 @@ HBITMAP CopyScreenToBitmap(LPRECT lpRect, BYTE *pData, BITMAPINFO *pHeader) BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); // select old bitmap back into memory DC and get handle to - // bitmap of the screen + // bitmap of the screen hBitmap = (HBITMAP) SelectObject(hMemDC, hOldBitmap); // Copy the bitmap data into the provided BYTE buffer diff --git a/plugins/pluginDirectShow/internals/DSDisplay.cxx b/plugins/pluginDirectShow/internals/DSDisplay.cxx index 326b86c..5cc1b04 100755 --- a/plugins/pluginDirectShow/internals/DSDisplay.cxx +++ b/plugins/pluginDirectShow/internals/DSDisplay.cxx @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -36,12 +36,11 @@ using namespace std; #define FSCREEN_MIN_IDEAL_WIDTH 352 #define FSCREEN_MIN_IDEAL_HEIGHT 288 -typedef struct tdshow_display_s -{ - TSK_DECLARE_OBJECT; +typedef struct tdshow_display_s { + TSK_DECLARE_OBJECT; - HWND hwnd; - DSDisplay* display; + HWND hwnd; + DSDisplay* display; } tdshow_display_t; typedef tsk_list_t tdshow_displays_L_t; @@ -53,504 +52,501 @@ static tdshow_displays_L_t* __directshow__Displays = tsk_null; /*== Predicate function to find tdshow_display_t object by HWND. */ static int __pred_find_display_by_hwnd(const tsk_list_item_t *item, const void *hWnd) { - if(item && item->data){ - const tdshow_display_t *display = (const tdshow_display_t *)item->data; - int ret = 0; - tsk_subsat_int32_ptr(display->hwnd, *((HWND*)hWnd), &ret); - return ret; - } - return -1; + if(item && item->data) { + const tdshow_display_t *display = (const tdshow_display_t *)item->data; + int ret = 0; + tsk_subsat_int32_ptr(display->hwnd, *((HWND*)hWnd), &ret); + return ret; + } + return -1; } // C Callback that dispatch event to the right display static LRESULT CALLBACK __directshow__WndProcWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - LRESULT result = FALSE; - BOOL resultSet = FALSE; - - if(__directshow__Displays){ - tsk_list_lock(__directshow__Displays); + LRESULT result = FALSE; + BOOL resultSet = FALSE; + + if(__directshow__Displays) { + tsk_list_lock(__directshow__Displays); - const tdshow_display_t *display = (const tdshow_display_t *)tsk_list_find_object_by_pred(__directshow__Displays, __pred_find_display_by_hwnd, &hWnd); - if((resultSet = (display && display->display))){ - result = display->display->handleEvents(hWnd, uMsg, wParam, lParam); - } + const tdshow_display_t *display = (const tdshow_display_t *)tsk_list_find_object_by_pred(__directshow__Displays, __pred_find_display_by_hwnd, &hWnd); + if((resultSet = (display && display->display))) { + result = display->display->handleEvents(hWnd, uMsg, wParam, lParam); + } - tsk_list_unlock(__directshow__Displays); - } + tsk_list_unlock(__directshow__Displays); + } - return resultSet ? result : DefWindowProc(hWnd, uMsg, wParam, lParam); + return resultSet ? result : DefWindowProc(hWnd, uMsg, wParam, lParam); } DSDisplay::DSDisplay(HRESULT *hr) { - this->window = NULL; - this->parentWindowProc = NULL; - this->hooked = false; - this->fullscreen = false; - this->bPluginFirefox = false; - this->top = 0; - this->left = 0; - this->width = this->imgWidth = 176; - this->height = this->imgHeight = 144; - this->fps = 15; - - this->graph = new DSDisplayGraph(hr); - if (FAILED(*hr)) return; + this->window = NULL; + this->parentWindowProc = NULL; + this->hooked = false; + this->fullscreen = false; + this->bPluginFirefox = false; + this->top = 0; + this->left = 0; + this->width = this->imgWidth = 176; + this->height = this->imgHeight = 144; + this->fps = 15; + + this->graph = new DSDisplayGraph(hr); + if (FAILED(*hr)) { + return; + } #if USE_OVERLAY - this->overlay = new DSDisplayOverlay(); + this->overlay = new DSDisplayOverlay(); #else - this->overlay = NULL; + this->overlay = NULL; #endif - - this->graph->getVideoWindow()->put_Visible(OAFALSE); + + this->graph->getVideoWindow()->put_Visible(OAFALSE); } DSDisplay::~DSDisplay() { - this->unhook(); + this->unhook(); - SAFE_DELETE_PTR(this->overlay); - SAFE_DELETE_PTR(this->graph); + SAFE_DELETE_PTR(this->overlay); + SAFE_DELETE_PTR(this->graph); } void DSDisplay::start() { - if (!this->graph->isRunning()){ - this->hook(); - } - if (!this->graph->isRunning() || this->graph->isPaused()){ - this->graph->start(); - } - this->graph->getVideoWindow()->put_Visible(OATRUE); + if (!this->graph->isRunning()) { + this->hook(); + } + if (!this->graph->isRunning() || this->graph->isPaused()) { + this->graph->start(); + } + this->graph->getVideoWindow()->put_Visible(OATRUE); } void DSDisplay::pause() { - this->graph->pause(); + this->graph->pause(); } void DSDisplay::stop() { - if (this->graph->isRunning()){ - this->setFullscreen(false); + if (this->graph->isRunning()) { + this->setFullscreen(false); - this->graph->stop(); - this->unhook(); - } + this->graph->stop(); + this->unhook(); + } } void DSDisplay::attach(INT64 parent) { - this->attach((void*)parent); + this->attach((void*)parent); } void DSDisplay::attach(void *parent) { - // Don't reattach if this is the same parent - if (this->isAttached() && parent){ - HWND hwnd = reinterpret_cast<HWND>(parent); - if (hwnd != this->window){ - this->detach(); - } - } - - // Gets the handle of the parent - this->window = reinterpret_cast<HWND>(parent); - // Hook to the parent WindowProc - this->hook(); + // Don't reattach if this is the same parent + if (this->isAttached() && parent) { + HWND hwnd = reinterpret_cast<HWND>(parent); + if (hwnd != this->window) { + this->detach(); + } + } + + // Gets the handle of the parent + this->window = reinterpret_cast<HWND>(parent); + // Hook to the parent WindowProc + this->hook(); #if USE_OVERLAY - // Allows the overlay to initialize - this->overlay->attach(this->window, this->graph); + // Allows the overlay to initialize + this->overlay->attach(this->window, this->graph); #endif } void DSDisplay::detach(void *parent) { - // The detach action is only valid and if this is the same parent - if (parent){ - HWND hwnd = reinterpret_cast<HWND>(parent); - if (hwnd == this->window){ - this->detach(); - } - } + // The detach action is only valid and if this is the same parent + if (parent) { + HWND hwnd = reinterpret_cast<HWND>(parent); + if (hwnd == this->window) { + this->detach(); + } + } } void DSDisplay::detach() { - if (!this->isAttached()){ - return; - } + if (!this->isAttached()) { + return; + } #if USE_OVERLAY - // Clean up overlay - this->overlay->detach(); + // Clean up overlay + this->overlay->detach(); #endif - // Unhook from the parent WindowProc - this->unhook(); + // Unhook from the parent WindowProc + this->unhook(); - // Set the handle of the parent to NULL - this->window = NULL; + // Set the handle of the parent to NULL + this->window = NULL; } bool DSDisplay::isAttached() { - return (this->window != NULL); + return (this->window != NULL); } int DSDisplay::getWidth() { - return this->width; + return this->width; } int DSDisplay::getHeight() { - return this->height; + return this->height; } void DSDisplay::setSize(int w, int h) { - //this->width = w; - //this->height = h; + //this->width = w; + //this->height = h; - if (!this->fullscreen){ - this->graph->setImageFormat(w, h); - if(this->hooked){ + if (!this->fullscreen) { + this->graph->setImageFormat(w, h); + if(this->hooked) { #if 0 - #if defined(VMR9_WINDOWLESS) - RECT rc; - SetRect(&rc, 0, 0, w, h); - this->graph->getWindowlessControl()->SetVideoPosition(&rc, &rc); - #else - this->graph->getVideoWindow()->SetWindowPosition(0, 0, this->width , this->height); - #endif +#if defined(VMR9_WINDOWLESS) + RECT rc; + SetRect(&rc, 0, 0, w, h); + this->graph->getWindowlessControl()->SetVideoPosition(&rc, &rc); +#else + this->graph->getVideoWindow()->SetWindowPosition(0, 0, this->width , this->height); #endif - } - } +#endif + } + } } void DSDisplay::applyRatio(RECT rect) { - long w = rect.right - rect.left; - long h = rect.bottom - rect.top; - float ratio = ((float)this->imgWidth/(float)this->imgHeight); - // (w/h)=ratio => - // 1) h=w/ratio - // and - // 2) w=h*ratio - this->width = (int)(w/ratio) > h ? (int)(h * ratio) : w; - this->height = (int)(this->width/ratio) > h ? h : (int)(this->width/ratio); - this->left = ((w - this->width) >> 1); - this->top = ((h - this->height) >> 1); + long w = rect.right - rect.left; + long h = rect.bottom - rect.top; + float ratio = ((float)this->imgWidth/(float)this->imgHeight); + // (w/h)=ratio => + // 1) h=w/ratio + // and + // 2) w=h*ratio + this->width = (int)(w/ratio) > h ? (int)(h * ratio) : w; + this->height = (int)(this->width/ratio) > h ? h : (int)(this->width/ratio); + this->left = ((w - this->width) >> 1); + this->top = ((h - this->height) >> 1); } bool DSDisplay::isFullscreen() { #if defined(VMR9_WINDOWLESS) - // TODO + // TODO #else - long result; - HRESULT hr = this->graph->getVideoWindow()->get_FullScreenMode(&result); - if (SUCCEEDED(hr)){ - this->fullscreen = (result == OATRUE); - } - else{ - TSK_DEBUG_ERROR("get_FullScreenMode failed with %ld", hr); - this->fullscreen = FALSE; - } + long result; + HRESULT hr = this->graph->getVideoWindow()->get_FullScreenMode(&result); + if (SUCCEEDED(hr)) { + this->fullscreen = (result == OATRUE); + } + else { + TSK_DEBUG_ERROR("get_FullScreenMode failed with %ld", hr); + this->fullscreen = FALSE; + } #endif - return this->fullscreen; + return this->fullscreen; } void DSDisplay::setFullscreen(bool value) { - if(!this->canFullscreen()){ - TSK_DEBUG_WARN("Cannot fullscreen"); - return; - } + if(!this->canFullscreen()) { + TSK_DEBUG_WARN("Cannot fullscreen"); + return; + } - HRESULT hr; + HRESULT hr; #if defined(VMR9_WINDOWLESS) - // TODO + // TODO #else - if (this->isFullscreen() == value){ - return; - } + if (this->isFullscreen() == value) { + return; + } - hr = this->graph->getVideoWindow()->put_FullScreenMode(value ? OATRUE : OAFALSE); - if (SUCCEEDED(hr)){ - this->fullscreen = value; + hr = this->graph->getVideoWindow()->put_FullScreenMode(value ? OATRUE : OAFALSE); + if (SUCCEEDED(hr)) { + this->fullscreen = value; #if USE_OVERLAY - this->overlay->show(this->fullscreen ? (OVERLAY_TIMEOUT * this->graph->getDisplayFps()) : 0); + this->overlay->show(this->fullscreen ? (OVERLAY_TIMEOUT * this->graph->getDisplayFps()) : 0); #endif - } - else{ - TSK_DEBUG_ERROR("put_FullScreenMode failed with %ld", hr); - } + } + else { + TSK_DEBUG_ERROR("put_FullScreenMode failed with %ld", hr); + } #endif } void DSDisplay::setPluginFirefox(bool value) { - bPluginFirefox = value; + bPluginFirefox = value; } bool DSDisplay::canFullscreen() { #if defined(VMR9_WINDOWLESS) - // TODO + // TODO #else - if(this->graph){ - UINT image_w, image_h; - - if( this->graph->getImageFormat(image_w, image_h) ){ - //this->graph->getVideoWindow()->GetMinIdealImageSize(&ideal_w, &ideal_h); - return (((long)image_w >= FSCREEN_MIN_IDEAL_WIDTH) && ((long)image_h >= FSCREEN_MIN_IDEAL_HEIGHT)); - } - } + if(this->graph) { + UINT image_w, image_h; + + if( this->graph->getImageFormat(image_w, image_h) ) { + //this->graph->getVideoWindow()->GetMinIdealImageSize(&ideal_w, &ideal_h); + return (((long)image_w >= FSCREEN_MIN_IDEAL_WIDTH) && ((long)image_h >= FSCREEN_MIN_IDEAL_HEIGHT)); + } + } #endif - return false; + return false; } void DSDisplay::setFps(int fps_) { - this->fps = fps_; - this->graph->setDisplayFps(fps_); + this->fps = fps_; + this->graph->setDisplayFps(fps_); } // w and h are the size of the buffer not the display void DSDisplay::handleVideoFrame(const void* data, int w, int h) { - if (this->graph->isRunning()){ - // The graph will take care of changing the source filter if needed - // in case of dimension change or anything else... - this->graph->handleFrame(data, w, h); - if(this->imgWidth != w || this->imgHeight != h){ - this->imgWidth = w; - this->imgHeight = h; - if(this->window){ - SendMessage(this->window, WM_SIZE, SIZE_RESTORED, MAKELPARAM(this->width , this->height)); - } - } + if (this->graph->isRunning()) { + // The graph will take care of changing the source filter if needed + // in case of dimension change or anything else... + this->graph->handleFrame(data, w, h); + if(this->imgWidth != w || this->imgHeight != h) { + this->imgWidth = w; + this->imgHeight = h; + if(this->window) { + SendMessage(this->window, WM_SIZE, SIZE_RESTORED, MAKELPARAM(this->width , this->height)); + } + } #if USE_OVERLAY - this->overlay->update(); + this->overlay->update(); #endif - } + } } LRESULT DSDisplay::handleEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch(uMsg) - { - case WM_CREATE: - case WM_SIZE: - case WM_MOVE: - { - RECT rect = {0}; - GetWindowRect(hWnd, &rect); - applyRatio(rect); + switch(uMsg) { + case WM_CREATE: + case WM_SIZE: + case WM_MOVE: { + RECT rect = {0}; + GetWindowRect(hWnd, &rect); + applyRatio(rect); #if defined(VMR9_WINDOWLESS) - this->graph->getWindowlessControl()->SetVideoPosition(&rect, &rect); + this->graph->getWindowlessControl()->SetVideoPosition(&rect, &rect); #else - this->graph->getVideoWindow()->SetWindowPosition(this->left, this->top, this->width , this->height); + this->graph->getVideoWindow()->SetWindowPosition(this->left, this->top, this->width , this->height); #endif - } - break; - - case WM_LBUTTONDBLCLK: - if(this->canFullscreen()){ - this->setFullscreen(true); - } - break; - - case WM_FULLSCREEN_SET: - if(this->canFullscreen()){ - this->setFullscreen(!this->isFullscreen()); - } - break; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_KEYDOWN: - if(this->isFullscreen()) - { + } + break; + + case WM_LBUTTONDBLCLK: + if(this->canFullscreen()) { + this->setFullscreen(true); + } + break; + + case WM_FULLSCREEN_SET: + if(this->canFullscreen()) { + this->setFullscreen(!this->isFullscreen()); + } + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_KEYDOWN: + if(this->isFullscreen()) { #if USE_OVERLAY - // Re-Show overlay - this->overlay->show(OVERLAY_TIMEOUT * this->graph->getDisplayFps()); + // Re-Show overlay + this->overlay->show(OVERLAY_TIMEOUT * this->graph->getDisplayFps()); #endif - } - break; - - case WM_CHAR: - case WM_KEYUP: - if(this->isFullscreen() && (wParam == 0x1B || wParam == VK_ESCAPE)) - { - // escape - this->setFullscreen(false); - } - - break; - - case WM_GRAPHNOTIFY: - { - long evCode; - LONG_PTR param1, param2; - HRESULT hr; - while (hr = this->graph->getMediaEvent()->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr)) - { - hr = this->graph->getMediaEvent()->FreeEventParams(evCode, param1, param2); - - switch(evCode) - { - case EC_FULLSCREEN_LOST: + } + break; + + case WM_CHAR: + case WM_KEYUP: + if(this->isFullscreen() && (wParam == 0x1B || wParam == VK_ESCAPE)) { + // escape + this->setFullscreen(false); + } + + break; + + case WM_GRAPHNOTIFY: { + long evCode; + LONG_PTR param1, param2; + HRESULT hr; + while (hr = this->graph->getMediaEvent()->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr)) { + hr = this->graph->getMediaEvent()->FreeEventParams(evCode, param1, param2); + + switch(evCode) { + case EC_FULLSCREEN_LOST: #if USE_OVERLAY - this->overlay->show(0); + this->overlay->show(0); #endif - break; - case EC_COMPLETE: - case EC_USERABORT: - default: - break; - } - } - } - break; + break; + case EC_COMPLETE: + case EC_USERABORT: + default: + break; + } + } + } + break; #if defined(VMR9_WINDOWLESS) - case WM_DISPLAYCHANGE: - { - this->graph->getWindowlessControl()->DisplayModeChanged(); - } - break; - case WM_PAINT: - { - RECT rect = {0}; - GetWindowRect(hWnd, &rect); - - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hWnd, &ps); - - this->graph->getWindowlessControl()->RepaintVideo(hWnd, hdc); - - EndPaint(hWnd, &ps); - } - break; -#endif + case WM_DISPLAYCHANGE: { + this->graph->getWindowlessControl()->DisplayModeChanged(); + } + break; + case WM_PAINT: { + RECT rect = {0}; + GetWindowRect(hWnd, &rect); + + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + + this->graph->getWindowlessControl()->RepaintVideo(hWnd, hdc); + + EndPaint(hWnd, &ps); + } + break; +#endif - } + } - return bPluginFirefox ? DefWindowProc(hWnd, uMsg, wParam, lParam) : CallWindowProc(this->parentWindowProc, hWnd, uMsg, wParam, lParam); + return bPluginFirefox ? DefWindowProc(hWnd, uMsg, wParam, lParam) : CallWindowProc(this->parentWindowProc, hWnd, uMsg, wParam, lParam); } void DSDisplay::hook() { - HRESULT hr; + HRESULT hr; - if (!this->window){ - return; - } + if (!this->window) { + return; + } - if(this->hooked){ - return; - } - this->hooked = TRUE; + if(this->hooked) { + return; + } + this->hooked = TRUE; - bool lock = (__directshow__Displays != NULL); + bool lock = (__directshow__Displays != NULL); - if(lock) - tsk_list_lock(__directshow__Displays); - { - // Gets the parent Window procedure + if(lock) { + tsk_list_lock(__directshow__Displays); + } + { + // Gets the parent Window procedure #if defined(_WIN32_WCE) - // Workaround for bug in SetWindowLong, call twice the API - //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) __directshow__WndProcWindow ); - //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) __directshow__WndProcWindow ); - //__directshow__Displays[this->window] = this; + // Workaround for bug in SetWindowLong, call twice the API + //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) __directshow__WndProcWindow ); + //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) __directshow__WndProcWindow ); + //__directshow__Displays[this->window] = this; #else - this->parentWindowProc = (WNDPROC) SetWindowLongPtr(this->window, GWLP_WNDPROC, (LONG_PTR) __directshow__WndProcWindow); - // Add this instance to the callback map - tsk_object_new(tdshow_display_def_t, this->window, this); + this->parentWindowProc = (WNDPROC) SetWindowLongPtr(this->window, GWLP_WNDPROC, (LONG_PTR) __directshow__WndProcWindow); + // Add this instance to the callback map + tsk_object_new(tdshow_display_def_t, this->window, this); #endif - } - if(lock) - tsk_list_unlock(__directshow__Displays); + } + if(lock) { + tsk_list_unlock(__directshow__Displays); + } - RECT rect; - GetWindowRect(this->window, &rect); - applyRatio(rect); + RECT rect; + GetWindowRect(this->window, &rect); + applyRatio(rect); #if defined(VMR9_WINDOWLESS) - rect.left = 0; - rect.top = 0; - rect.right = this->width; - rect.bottom = this->height; - - // TODO : Review - hr = this->graph->getWindowlessControl()->SetVideoClippingWindow(this->window); - hr = this->graph->getWindowlessControl()->SetBorderColor(RGB(0, 0, 128)); - hr = this->graph->getWindowlessControl()->SetVideoPosition(NULL, &rect); + rect.left = 0; + rect.top = 0; + rect.right = this->width; + rect.bottom = this->height; + + // TODO : Review + hr = this->graph->getWindowlessControl()->SetVideoClippingWindow(this->window); + hr = this->graph->getWindowlessControl()->SetBorderColor(RGB(0, 0, 128)); + hr = this->graph->getWindowlessControl()->SetVideoPosition(NULL, &rect); #else - // TODO : Review the order - hr = this->graph->getVideoWindow()->put_Owner((OAHWND) this->window); - hr = this->graph->getVideoWindow()->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - hr = this->graph->getVideoWindow()->SetWindowPosition(this->left, this->top, this->width, this->height); - hr = this->graph->getVideoWindow()->put_MessageDrain((OAHWND) this->window); - hr = this->graph->getVideoWindow()->put_Visible(OATRUE); + // TODO : Review the order + hr = this->graph->getVideoWindow()->put_Owner((OAHWND) this->window); + hr = this->graph->getVideoWindow()->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + hr = this->graph->getVideoWindow()->SetWindowPosition(this->left, this->top, this->width, this->height); + hr = this->graph->getVideoWindow()->put_MessageDrain((OAHWND) this->window); + hr = this->graph->getVideoWindow()->put_Visible(OATRUE); #endif - hr = this->graph->getMediaEvent()->SetNotifyWindow((OAHWND) this->window, WM_GRAPHNOTIFY, 0); + hr = this->graph->getMediaEvent()->SetNotifyWindow((OAHWND) this->window, WM_GRAPHNOTIFY, 0); } void DSDisplay::unhook() { - HRESULT hr; + HRESULT hr; - if(!this->window){ - return; - } + if(!this->window) { + return; + } - if(!this->hooked){ - return; - } - - hr = this->graph->getMediaEvent()->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0); + if(!this->hooked) { + return; + } + + hr = this->graph->getMediaEvent()->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0); #if defined(VMR9_WINDOWLESS) - // TODO : Review - hr = this->graph->getWindowlessControl()->SetVideoClippingWindow(NULL); + // TODO : Review + hr = this->graph->getWindowlessControl()->SetVideoClippingWindow(NULL); #else - // TODO : Review the order - hr = this->graph->getVideoWindow()->put_Visible(OAFALSE); - hr = this->graph->getVideoWindow()->put_MessageDrain((OAHWND) NULL); - hr = this->graph->getVideoWindow()->put_Owner((OAHWND) NULL); - hr = this->graph->getVideoWindow()->put_AutoShow(OAFALSE); + // TODO : Review the order + hr = this->graph->getVideoWindow()->put_Visible(OAFALSE); + hr = this->graph->getVideoWindow()->put_MessageDrain((OAHWND) NULL); + hr = this->graph->getVideoWindow()->put_Owner((OAHWND) NULL); + hr = this->graph->getVideoWindow()->put_AutoShow(OAFALSE); #endif - bool lock = (__directshow__Displays != NULL); - if(lock) - tsk_list_lock(__directshow__Displays); - { - // Remove this instance from the callback map - tsk_list_remove_item_by_pred(__directshow__Displays, __pred_find_display_by_hwnd, &this->window); - // Restore parent Window procedure + bool lock = (__directshow__Displays != NULL); + if(lock) { + tsk_list_lock(__directshow__Displays); + } + { + // Remove this instance from the callback map + tsk_list_remove_item_by_pred(__directshow__Displays, __pred_find_display_by_hwnd, &this->window); + // Restore parent Window procedure #if defined(_WIN32_WCE) - // Workaround for bug in SetWindowLong, call twice the API - //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) this->parentWindowProc ); - //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) this->parentWindowProc ); + // Workaround for bug in SetWindowLong, call twice the API + //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) this->parentWindowProc ); + //this->parentWindowProc = (WNDPROC)SetWindowLong( this->window, GWL_WNDPROC, (LONG) this->parentWindowProc ); #else - SetWindowLongPtr(this->window, GWLP_WNDPROC, (LONG_PTR) this->parentWindowProc); + SetWindowLongPtr(this->window, GWLP_WNDPROC, (LONG_PTR) this->parentWindowProc); #endif - } - if(lock) - tsk_list_unlock(__directshow__Displays); + } + if(lock) { + tsk_list_unlock(__directshow__Displays); + } - this->hooked = FALSE; + this->hooked = FALSE; } @@ -568,55 +564,58 @@ void DSDisplay::unhook() // static tsk_object_t* tdshow_display_ctor(tsk_object_t * self, va_list * app) { - tdshow_display_t *display = (tdshow_display_t *)self; - - if(display){ - display->hwnd = va_arg(*app, HWND); - display->display = va_arg(*app, DSDisplay*); - - if(!__directshow__Displays){ - __directshow__Displays = tsk_list_create(); - } - tsk_list_push_back_data(__directshow__Displays, (void**)&display); - } - - return self; + tdshow_display_t *display = (tdshow_display_t *)self; + + if(display) { + display->hwnd = va_arg(*app, HWND); + display->display = va_arg(*app, DSDisplay*); + + if(!__directshow__Displays) { + __directshow__Displays = tsk_list_create(); + } + tsk_list_push_back_data(__directshow__Displays, (void**)&display); + } + + return self; } static tsk_object_t* tdshow_display_dtor(tsk_object_t * self) -{ - tdshow_display_t *display = (tdshow_display_t *)self; - if(display){ - if(__directshow__Displays){ - tsk_list_remove_item_by_data(__directshow__Displays, display); - //if(TSK_LIST_IS_EMPTY(__directshow__Displays)){ - // TSK_OBJECT_SAFE_FREE(__directshow__Displays); - //} - } - } - - return self; +{ + tdshow_display_t *display = (tdshow_display_t *)self; + if(display) { + if(__directshow__Displays) { + tsk_list_remove_item_by_data(__directshow__Displays, display); + //if(TSK_LIST_IS_EMPTY(__directshow__Displays)){ + // TSK_OBJECT_SAFE_FREE(__directshow__Displays); + //} + } + } + + return self; } static int tdshow_display_cmp(const tsk_object_t *_d1, const tsk_object_t *_d2) { - const tdshow_display_t *d1 = (const tdshow_display_t *)_d1; - const tdshow_display_t *d2 = (const tdshow_display_t *)_d2; - - if(d1 && d2){ - int ret = 0; - tsk_subsat_int32_ptr(d1->hwnd, d2->hwnd, &ret); - return ret; - } - else if(!d1 && !d2) return 0; - else return -1; + const tdshow_display_t *d1 = (const tdshow_display_t *)_d1; + const tdshow_display_t *d2 = (const tdshow_display_t *)_d2; + + if(d1 && d2) { + int ret = 0; + tsk_subsat_int32_ptr(d1->hwnd, d2->hwnd, &ret); + return ret; + } + else if(!d1 && !d2) { + return 0; + } + else { + return -1; + } } -static const tsk_object_def_t tdshow_display_def_s = -{ - sizeof(tdshow_display_t), - tdshow_display_ctor, - tdshow_display_dtor, - tdshow_display_cmp, +static const tsk_object_def_t tdshow_display_def_s = { + sizeof(tdshow_display_t), + tdshow_display_ctor, + tdshow_display_dtor, + tdshow_display_cmp, }; extern const tsk_object_def_t *tdshow_display_def_t = &tdshow_display_def_s; diff --git a/plugins/pluginDirectShow/internals/DSDisplay.h b/plugins/pluginDirectShow/internals/DSDisplay.h index b2985ef..c20c17c 100755 --- a/plugins/pluginDirectShow/internals/DSDisplay.h +++ b/plugins/pluginDirectShow/internals/DSDisplay.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -32,53 +32,53 @@ class DSDisplay { public: - DSDisplay(HRESULT *hr); - virtual ~DSDisplay(); + DSDisplay(HRESULT *hr); + virtual ~DSDisplay(); - virtual void attach(INT64 parent); - virtual void attach(void *parent); - virtual void detach(void *parent); - virtual void detach(); - virtual bool isAttached(); + virtual void attach(INT64 parent); + virtual void attach(void *parent); + virtual void detach(void *parent); + virtual void detach(); + virtual bool isAttached(); - virtual void start(); - virtual void pause(); - virtual void stop(); + virtual void start(); + virtual void pause(); + virtual void stop(); - virtual int getWidth(); - virtual int getHeight(); - virtual void setSize(int w, int h); + virtual int getWidth(); + virtual int getHeight(); + virtual void setSize(int w, int h); - virtual bool isFullscreen(); - virtual void setFullscreen(bool value); - virtual void setPluginFirefox(bool value); + virtual bool isFullscreen(); + virtual void setFullscreen(bool value); + virtual void setPluginFirefox(bool value); - virtual bool canFullscreen(); + virtual bool canFullscreen(); - virtual void setFps(int fps_); + virtual void setFps(int fps_); - virtual void handleVideoFrame(const void* data, int w, int h); + virtual void handleVideoFrame(const void* data, int w, int h); - LRESULT handleEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT handleEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); private: - void hook(); - void unhook(); - void applyRatio(RECT rect); + void hook(); + void unhook(); + void applyRatio(RECT rect); private: - DSDisplayGraph *graph; - DSDisplayOverlay *overlay; - - int fps; - int left, top, width, height, imgWidth, imgHeight; - - bool bPluginFirefox; - bool fullscreen; - HWND window; - WNDPROC parentWindowProc; - - bool hooked; + DSDisplayGraph *graph; + DSDisplayOverlay *overlay; + + int fps; + int left, top, width, height, imgWidth, imgHeight; + + bool bPluginFirefox; + bool fullscreen; + HWND window; + WNDPROC parentWindowProc; + + bool hooked; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSDisplayGraph.cxx b/plugins/pluginDirectShow/internals/DSDisplayGraph.cxx index b2da43b..75b00f4 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayGraph.cxx +++ b/plugins/pluginDirectShow/internals/DSDisplayGraph.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -31,315 +31,359 @@ using namespace std; DSDisplayGraph::DSDisplayGraph(HRESULT *hr) { - this->running = FALSE; - this->paused = FALSE; - this->fps = 15; - - this->graphBuilder = NULL; + this->running = FALSE; + this->paused = FALSE; + this->fps = 15; + + this->graphBuilder = NULL; - this->sourceFilter = NULL; - this->colorspaceConverterFilter = NULL; - this->videoRendererFilter = NULL; + this->sourceFilter = NULL; + this->colorspaceConverterFilter = NULL; + this->videoRendererFilter = NULL; - this->mediaController = NULL; - this->mediaEvent = NULL; - this->videoWindow = NULL; + this->mediaController = NULL; + this->mediaEvent = NULL; + this->videoWindow = NULL; #if defined(VMR) ||defined(VMR9) || defined(VMR9_WINDOWLESS) - this->mixerBitmap = NULL; - this->filterConfig = NULL; + this->mixerBitmap = NULL; + this->filterConfig = NULL; #endif #if defined(VMR9_WINDOWLESS) - this->windowlessControl = NULL; + this->windowlessControl = NULL; #endif - *hr = this->createDisplayGraph(); - if (FAILED(*hr)) return; + *hr = this->createDisplayGraph(); + if (FAILED(*hr)) { + return; + } - *hr = this->connect(); - if (FAILED(*hr)) return; + *hr = this->connect(); + if (FAILED(*hr)) { + return; + } } DSDisplayGraph::~DSDisplayGraph() { - this->disconnect(); + this->disconnect(); #if defined(VMR9_WINDOWLESS) - SAFE_RELEASE(this->windowlessControl); + SAFE_RELEASE(this->windowlessControl); #endif #if defined(VMR) ||defined(VMR9) || defined(VMR9_WINDOWLESS) - SAFE_RELEASE(this->filterConfig); - SAFE_RELEASE(this->mixerBitmap); + SAFE_RELEASE(this->filterConfig); + SAFE_RELEASE(this->mixerBitmap); #endif - SAFE_RELEASE(this->videoWindow); - SAFE_RELEASE(this->mediaEvent); - SAFE_RELEASE(this->mediaController); + SAFE_RELEASE(this->videoWindow); + SAFE_RELEASE(this->mediaEvent); + SAFE_RELEASE(this->mediaController); - SAFE_RELEASE(this->colorspaceConverterFilter); - SAFE_RELEASE(this->videoRendererFilter); - //SAFE_RELEASE(this->sourceFilter); + SAFE_RELEASE(this->colorspaceConverterFilter); + SAFE_RELEASE(this->videoRendererFilter); + //SAFE_RELEASE(this->sourceFilter); - SAFE_RELEASE(this->graphBuilder); + SAFE_RELEASE(this->graphBuilder); } void DSDisplayGraph::setDisplayFps(int fps_) { - this->fps = fps_; - if(this->sourceFilter){ - this->sourceFilter->setFps(fps_); - } + this->fps = fps_; + if(this->sourceFilter) { + this->sourceFilter->setFps(fps_); + } } bool DSDisplayGraph::getImageFormat(UINT &width, UINT &height) { - if(this->sourceFilter){ - return this->sourceFilter->getImageFormat(width, height); - } - return false; + if(this->sourceFilter) { + return this->sourceFilter->getImageFormat(width, height); + } + return false; } bool DSDisplayGraph::setImageFormat(UINT width, UINT height) { - bool ret = true; - if(this->sourceFilter){ - UINT w=width, h = height; - if(this->sourceFilter->getImageFormat(w, h)){ - if(w!= width || h!=height){ // Image format has changed - bool reconnect = this->connected; // IMPORTANT: Must reconnect all elements - HRESULT hr; - if(reconnect){ - if((hr = this->disconnect()) != S_OK){ - return false; - } - } - ret = (this->sourceFilter->setImageFormat(width, height) == S_OK); - if(reconnect){ - if((hr = this->connect())){ - return false; - } - } - } - } - } - return ret; + bool ret = true; + if(this->sourceFilter) { + UINT w=width, h = height; + if(this->sourceFilter->getImageFormat(w, h)) { + if(w!= width || h!=height) { // Image format has changed + bool reconnect = this->connected; // IMPORTANT: Must reconnect all elements + HRESULT hr; + if(reconnect) { + if((hr = this->disconnect()) != S_OK) { + return false; + } + } + ret = (this->sourceFilter->setImageFormat(width, height) == S_OK); + if(reconnect) { + if((hr = this->connect())) { + return false; + } + } + } + } + } + return ret; } HRESULT DSDisplayGraph::connect() { - HRESULT hr; - - if((hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorspaceConverterFilter)) != S_OK){ - TSK_DEBUG_ERROR("Failed to connect sourcefilter with the colorspace"); - return hr; - } - if((hr = ConnectFilters(this->graphBuilder, this->colorspaceConverterFilter, this->videoRendererFilter)) != S_OK){ - TSK_DEBUG_ERROR("Failed to connect colorspace with the videorenderer"); - return hr; - } - - this->connected = true; - return S_OK; + HRESULT hr; + + if((hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->colorspaceConverterFilter)) != S_OK) { + TSK_DEBUG_ERROR("Failed to connect sourcefilter with the colorspace"); + return hr; + } + if((hr = ConnectFilters(this->graphBuilder, this->colorspaceConverterFilter, this->videoRendererFilter)) != S_OK) { + TSK_DEBUG_ERROR("Failed to connect colorspace with the videorenderer"); + return hr; + } + + this->connected = true; + return S_OK; } HRESULT DSDisplayGraph::disconnect() { - HRESULT hr; - - if((hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorspaceConverterFilter)) != S_OK){ - TSK_DEBUG_ERROR("Failed to disconnect sourcefilter with the colorspace"); - return hr; - } - if((hr = DisconnectFilters(this->graphBuilder, this->colorspaceConverterFilter, this->videoRendererFilter)) != S_OK){ - TSK_DEBUG_ERROR("Failed to connect colorspace with the videorenderer"); - return hr; - } - - this->connected = false; - return S_OK; + HRESULT hr; + + if((hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->colorspaceConverterFilter)) != S_OK) { + TSK_DEBUG_ERROR("Failed to disconnect sourcefilter with the colorspace"); + return hr; + } + if((hr = DisconnectFilters(this->graphBuilder, this->colorspaceConverterFilter, this->videoRendererFilter)) != S_OK) { + TSK_DEBUG_ERROR("Failed to connect colorspace with the videorenderer"); + return hr; + } + + this->connected = false; + return S_OK; } HRESULT DSDisplayGraph::start() { - HRESULT hr; - this->running = true; - this->sourceFilter->reset(); - - hr = this->mediaController->Run(); - if (!SUCCEEDED(hr)){ - TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Run() has failed with %ld", hr); - } - return hr; + HRESULT hr; + this->running = true; + this->sourceFilter->reset(); + + hr = this->mediaController->Run(); + if (!SUCCEEDED(hr)) { + TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Run() has failed with %ld", hr); + } + return hr; } HRESULT DSDisplayGraph::pause() { - HRESULT hr = S_OK; - if(isRunning() && !isPaused()){ - hr = this->mediaController->Pause(); - if(SUCCEEDED(hr)){ - this->paused = true; - } - } - return hr; + HRESULT hr = S_OK; + if(isRunning() && !isPaused()) { + hr = this->mediaController->Pause(); + if(SUCCEEDED(hr)) { + this->paused = true; + } + } + return hr; } HRESULT DSDisplayGraph::stop() { - HRESULT hr; + HRESULT hr; - hr = this->mediaController->Pause(); - if (hr == S_FALSE){ - TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Pause() has failed with %ld. Waiting for transition.", hr); - FILTER_STATE pfs; - hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); - } + hr = this->mediaController->Pause(); + if (hr == S_FALSE) { + TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Pause() has failed with %ld. Waiting for transition.", hr); + FILTER_STATE pfs; + hr = this->mediaController->GetState(2500, (OAFilterState*) &pfs); + } - hr = this->mediaController->Stop(); - if (!SUCCEEDED(hr)){ - TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Stop() has failed with %ld", hr); - } + hr = this->mediaController->Stop(); + if (!SUCCEEDED(hr)) { + TSK_DEBUG_ERROR("DSDisplayGraph::mediaController->Stop() has failed with %ld", hr); + } - this->running = false; - this->paused = false; + this->running = false; + this->paused = false; - return hr; + return hr; } bool DSDisplayGraph::isRunning() { - return this->running; + return this->running; } bool DSDisplayGraph::isPaused() { - return this->paused; + return this->paused; } void DSDisplayGraph::handleFrame(const void* data, int w, int h) { - HRESULT hr; - - if(!this->sourceFilter){ - TSK_DEBUG_ERROR("Invalid parameter"); - return; - } - - if(!data || !this->running){ - this->sourceFilter->setBuffer(NULL, (w*h*3)); - return; - } - - hr = this->sourceFilter->setImageFormat(w, h); - if (hr == S_OK){ - this->stop(); - - this->disconnect(); - this->connect(); - - this->start(); - } - - this->sourceFilter->setBuffer((void*)data, (w*h*3)); + HRESULT hr; + + if(!this->sourceFilter) { + TSK_DEBUG_ERROR("Invalid parameter"); + return; + } + + if(!data || !this->running) { + this->sourceFilter->setBuffer(NULL, (w*h*3)); + return; + } + + hr = this->sourceFilter->setImageFormat(w, h); + if (hr == S_OK) { + this->stop(); + + this->disconnect(); + this->connect(); + + this->start(); + } + + this->sourceFilter->setBuffer((void*)data, (w*h*3)); } HRESULT DSDisplayGraph::createDisplayGraph() { - HRESULT hr; + HRESULT hr; - // Create the graph builder - hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder); - if(FAILED(hr)) return hr; + // Create the graph builder + hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder); + if(FAILED(hr)) { + return hr; + } - // Create my custom filter - LPUNKNOWN pUnk = NULL; - this->sourceFilter = new DSOutputFilter(pUnk, &hr /*, this*/); - if(FAILED(hr) || this->sourceFilter == NULL) return hr; + // Create my custom filter + LPUNKNOWN pUnk = NULL; + this->sourceFilter = new DSOutputFilter(pUnk, &hr /*, this*/); + if(FAILED(hr) || this->sourceFilter == NULL) { + return hr; + } - // Create the color space convertor filter - hr = COCREATE(CLSID_Colour, IID_IBaseFilter, this->colorspaceConverterFilter); - if(FAILED(hr)) return hr; + // Create the color space convertor filter + hr = COCREATE(CLSID_Colour, IID_IBaseFilter, this->colorspaceConverterFilter); + if(FAILED(hr)) { + return hr; + } #if defined(VMR) - // Create the video mixing renderer based on Direct X - hr = COCREATE(CLSID_VideoMixingRenderer, IID_IBaseFilter, this->videoRendererFilter); - if(FAILED(hr)) return hr; + // Create the video mixing renderer based on Direct X + hr = COCREATE(CLSID_VideoMixingRenderer, IID_IBaseFilter, this->videoRendererFilter); + if(FAILED(hr)) { + return hr; + } #elif defined(VMR9) || defined(VMR9_WINDOWLESS) - // Create the video mixing renderer based on Direct X 9.0 - hr = COCREATE(CLSID_VideoMixingRenderer9, IID_IBaseFilter, this->videoRendererFilter); - if(FAILED(hr)) return hr; + // Create the video mixing renderer based on Direct X 9.0 + hr = COCREATE(CLSID_VideoMixingRenderer9, IID_IBaseFilter, this->videoRendererFilter); + if(FAILED(hr)) { + return hr; + } #else - // Create the video renderer - hr = COCREATE(CLSID_VideoRenderer, IID_IBaseFilter, this->videoRendererFilter); - if(FAILED(hr)) return hr; + // Create the video renderer + hr = COCREATE(CLSID_VideoRenderer, IID_IBaseFilter, this->videoRendererFilter); + if(FAILED(hr)) { + return hr; + } #endif - // Add dource filter to the graph - hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_OUTPUT); - if(FAILED(hr)) return hr; + // Add dource filter to the graph + hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_OUTPUT); + if(FAILED(hr)) { + return hr; + } - // Add the color space convertor to the graph - hr = this->graphBuilder->AddFilter(this->colorspaceConverterFilter, FILTER_COLORSPACE_CONVERTOR); - if(FAILED(hr)) return hr; + // Add the color space convertor to the graph + hr = this->graphBuilder->AddFilter(this->colorspaceConverterFilter, FILTER_COLORSPACE_CONVERTOR); + if(FAILED(hr)) { + return hr; + } - // Add video renderer to the graph - hr = this->graphBuilder->AddFilter(this->videoRendererFilter, FILTER_VIDEO_RENDERER); - if(FAILED(hr)) return hr; + // Add video renderer to the graph + hr = this->graphBuilder->AddFilter(this->videoRendererFilter, FILTER_VIDEO_RENDERER); + if(FAILED(hr)) { + return hr; + } - // Find media control - hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController); - if(FAILED(hr)) return hr; + // Find media control + hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController); + if(FAILED(hr)) { + return hr; + } - // Find media event - hr = QUERY(this->graphBuilder, IID_IMediaEventEx, this->mediaEvent); - if(FAILED(hr)) return hr; - // hr = this->mediaEvent->SetNotifyFlags(AM_MEDIAEVENT_NONOTIFY); + // Find media event + hr = QUERY(this->graphBuilder, IID_IMediaEventEx, this->mediaEvent); + if(FAILED(hr)) { + return hr; + } + // hr = this->mediaEvent->SetNotifyFlags(AM_MEDIAEVENT_NONOTIFY); #if defined(VMR) - // Find the bitmap mixer (Direct X) - hr = QUERY(this->videoRendererFilter, IID_IVMRMixerBitmap, this->mixerBitmap); - if(FAILED(hr)) return hr; - - // Find the bitmap configurer (Direct X) - hr = QUERY(this->videoRendererFilter, IID_IVMRFilterConfig, this->filterConfig); - if(FAILED(hr)) return hr; - - // Set the number of streams (Direct X) - hr = this->filterConfig->SetNumberOfStreams(1); - if(FAILED(hr)) return hr; + // Find the bitmap mixer (Direct X) + hr = QUERY(this->videoRendererFilter, IID_IVMRMixerBitmap, this->mixerBitmap); + if(FAILED(hr)) { + return hr; + } + + // Find the bitmap configurer (Direct X) + hr = QUERY(this->videoRendererFilter, IID_IVMRFilterConfig, this->filterConfig); + if(FAILED(hr)) { + return hr; + } + + // Set the number of streams (Direct X) + hr = this->filterConfig->SetNumberOfStreams(1); + if(FAILED(hr)) { + return hr; + } #elif defined(VMR9) || defined(VMR9_WINDOWLESS) - // Find the bitmap mixer (Direct X 9.0) - hr = QUERY(this->videoRendererFilter, IID_IVMRMixerBitmap9, this->mixerBitmap); - if(FAILED(hr)) return hr; - - // Find the bitmap configurer (Direct X 9.0) - hr = QUERY(this->videoRendererFilter, IID_IVMRFilterConfig9, this->filterConfig); - if(FAILED(hr)) return hr; - - // Set the number of streams (Direct X 9.0) - hr = this->filterConfig->SetNumberOfStreams(1); - if(FAILED(hr)) return hr; + // Find the bitmap mixer (Direct X 9.0) + hr = QUERY(this->videoRendererFilter, IID_IVMRMixerBitmap9, this->mixerBitmap); + if(FAILED(hr)) { + return hr; + } + + // Find the bitmap configurer (Direct X 9.0) + hr = QUERY(this->videoRendererFilter, IID_IVMRFilterConfig9, this->filterConfig); + if(FAILED(hr)) { + return hr; + } + + // Set the number of streams (Direct X 9.0) + hr = this->filterConfig->SetNumberOfStreams(1); + if(FAILED(hr)) { + return hr; + } #endif #if defined(VMR9_WINDOWLESS) - // Set the rendering mode (Direct X 9.0) - hr = this->filterConfig->SetRenderingMode(VMR9Mode_Windowless); - if(FAILED(hr)) return hr; - - // Find the windowless control (Direct X 9.0) - hr = QUERY(this->videoRendererFilter, IID_IVMRWindowlessControl9, this->windowlessControl); - if(FAILED(hr)) return hr; + // Set the rendering mode (Direct X 9.0) + hr = this->filterConfig->SetRenderingMode(VMR9Mode_Windowless); + if(FAILED(hr)) { + return hr; + } + + // Find the windowless control (Direct X 9.0) + hr = QUERY(this->videoRendererFilter, IID_IVMRWindowlessControl9, this->windowlessControl); + if(FAILED(hr)) { + return hr; + } #else - // Find IVideoWindow interface - hr = QUERY(this->graphBuilder, IID_IVideoWindow, this->videoWindow); - if(FAILED(hr)) return hr; + // Find IVideoWindow interface + hr = QUERY(this->graphBuilder, IID_IVideoWindow, this->videoWindow); + if(FAILED(hr)) { + return hr; + } #endif - return hr; + return hr; } diff --git a/plugins/pluginDirectShow/internals/DSDisplayGraph.h b/plugins/pluginDirectShow/internals/DSDisplayGraph.h index c9080fe..4260e45 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayGraph.h +++ b/plugins/pluginDirectShow/internals/DSDisplayGraph.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -39,72 +39,90 @@ class DSDisplayGraph { public: - DSDisplayGraph(HRESULT *hr); - virtual ~DSDisplayGraph(); - - int getDisplayFps() { return this->fps; }; - void setDisplayFps(int fps_); - - bool getImageFormat(UINT &width, UINT &height); - bool setImageFormat(UINT width, UINT height); - - HRESULT connect(); - HRESULT disconnect(); - - HRESULT start(); - HRESULT pause(); - HRESULT stop(); - bool isRunning(); - bool isPaused(); - - IMediaEventEx *getMediaEvent() { return this->mediaEvent; }; - IVideoWindow *getVideoWindow() { return this->videoWindow; }; - DSOutputFilter *getSourceFilter() { return this->sourceFilter; }; + DSDisplayGraph(HRESULT *hr); + virtual ~DSDisplayGraph(); + + int getDisplayFps() { + return this->fps; + }; + void setDisplayFps(int fps_); + + bool getImageFormat(UINT &width, UINT &height); + bool setImageFormat(UINT width, UINT height); + + HRESULT connect(); + HRESULT disconnect(); + + HRESULT start(); + HRESULT pause(); + HRESULT stop(); + bool isRunning(); + bool isPaused(); + + IMediaEventEx *getMediaEvent() { + return this->mediaEvent; + }; + IVideoWindow *getVideoWindow() { + return this->videoWindow; + }; + DSOutputFilter *getSourceFilter() { + return this->sourceFilter; + }; #if defined(VMR) - IVMRMixerBitmap *getMixerBitmap() { return this->mixerBitmap; }; + IVMRMixerBitmap *getMixerBitmap() { + return this->mixerBitmap; + }; #elif defined(VMR9) - IVMRMixerBitmap9 *getMixerBitmap() { return this->mixerBitmap; }; + IVMRMixerBitmap9 *getMixerBitmap() { + return this->mixerBitmap; + }; #elif defined(VMR9_WINDOWLESS) - IVMRMixerBitmap9 *getMixerBitmap() { return this->mixerBitmap; }; - IVMRMixerControl9 *getMixerControl() { return this->mixerControl; }; - IVMRWindowlessControl9 *getWindowlessControl() { return this->windowlessControl; }; + IVMRMixerBitmap9 *getMixerBitmap() { + return this->mixerBitmap; + }; + IVMRMixerControl9 *getMixerControl() { + return this->mixerControl; + }; + IVMRWindowlessControl9 *getWindowlessControl() { + return this->windowlessControl; + }; #endif - void handleFrame(const void* data, int w, int h); + void handleFrame(const void* data, int w, int h); private: - HRESULT createDisplayGraph(); + HRESULT createDisplayGraph(); private: - IGraphBuilder *graphBuilder; + IGraphBuilder *graphBuilder; - DSOutputFilter *sourceFilter; - IBaseFilter *colorspaceConverterFilter; - IBaseFilter *videoRendererFilter; + DSOutputFilter *sourceFilter; + IBaseFilter *colorspaceConverterFilter; + IBaseFilter *videoRendererFilter; - IMediaControl *mediaController; - IMediaEventEx *mediaEvent; - IVideoWindow *videoWindow; + IMediaControl *mediaController; + IMediaEventEx *mediaEvent; + IVideoWindow *videoWindow; #if defined(VMR) - IVMRMixerBitmap *mixerBitmap; - IVMRFilterConfig *filterConfig; + IVMRMixerBitmap *mixerBitmap; + IVMRFilterConfig *filterConfig; #elif defined(VMR9) - IVMRMixerBitmap9 *mixerBitmap; - IVMRMixerControl9 *mixerControl; - IVMRFilterConfig9 *filterConfig; + IVMRMixerBitmap9 *mixerBitmap; + IVMRMixerControl9 *mixerControl; + IVMRFilterConfig9 *filterConfig; #elif defined(VMR9_WINDOWLESS) - IVMRMixerBitmap9 *mixerBitmap; - IVMRMixerControl9 *mixerControl; - IVMRFilterConfig9 *filterConfig; - IVMRWindowlessControl9 *windowlessControl; + IVMRMixerBitmap9 *mixerBitmap; + IVMRMixerControl9 *mixerControl; + IVMRFilterConfig9 *filterConfig; + IVMRWindowlessControl9 *windowlessControl; #endif - bool connected; - bool running; - bool paused; - int fps; + bool connected; + bool running; + bool paused; + int fps; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR.cxx b/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR.cxx index dacea84..188f7ec 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR.cxx +++ b/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR.cxx @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -39,9 +39,9 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; DSDisplayOverlay::DSDisplayOverlay() { - this->window = NULL; - this->hdcBmp = NULL; - this->hbmOld = NULL; + this->window = NULL; + this->hdcBmp = NULL; + this->hbmOld = NULL; } DSDisplayOverlay::~DSDisplayOverlay() @@ -50,130 +50,122 @@ DSDisplayOverlay::~DSDisplayOverlay() void DSDisplayOverlay::attach(HWND parent, DSDisplayGraph *graph) { - HRESULT hr; - - // Gets the handle of the parent and the graph - this->window = parent; - this->displayGraph = graph; - - if (this->window) - { - // Hack to get module of the current code - TCHAR *modulePath = (TCHAR *) calloc(255, sizeof(TCHAR)); - GetModuleFileName((HINSTANCE)&__ImageBase, modulePath, 255); - HMODULE module = GetModuleHandle(modulePath); - delete[] modulePath; - if (!module) - { - cout << "Failed to get current module"; - return; - } - - HBITMAP bitmap = LoadBitmap(module, MAKEINTRESOURCE(IDB_BITMAP_OVERLAY)); - if (!bitmap) - { - cout << "Failed to load overlay bitmap" << endl; - return; - } - - RECT rect; - hr = GetWindowRect(this->window, &rect); - if (FAILED(hr)) - { - cout << "Failed to get window size" << endl; - return; - } - - BITMAP bm; - HDC hdc = GetDC(this->window); - this->hdcBmp = CreateCompatibleDC(hdc); - ReleaseDC(this->window, hdc); - - GetObject(bitmap, sizeof(bm), &bm); - this->hbmOld= (HBITMAP) SelectObject(this->hdcBmp, bitmap); - - ZeroMemory(&this->alphaBitmap, sizeof(VMRALPHABITMAP)); - this->alphaBitmap.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY; - this->alphaBitmap.hdc = this->hdcBmp; - this->alphaBitmap.clrSrcKey = 0x00FF00FF; - // Source rectangle - this->alphaBitmap.rSrc.left = 0; - this->alphaBitmap.rSrc.top = 0; - this->alphaBitmap.rSrc.right = bm.bmWidth; - this->alphaBitmap.rSrc.bottom = bm.bmHeight; - // Destination rectangle - this->alphaBitmap.rDest.left = (rect.right - rect.left - bm.bmWidth) / 2.0; - this->alphaBitmap.rDest.top = (rect.bottom - rect.top - bm.bmHeight) / 2.0; - this->alphaBitmap.rDest.right = this->alphaBitmap.rDest.left + bm.bmWidth; - this->alphaBitmap.rDest.bottom = this->alphaBitmap.rDest.top + bm.bmHeight; - this->alphaBitmap.rDest.left /= (rect.right - rect.left); - this->alphaBitmap.rDest.top /= (rect.bottom - rect.top); - this->alphaBitmap.rDest.right /= (rect.right - rect.left); - this->alphaBitmap.rDest.bottom /= (rect.bottom - rect.top); - // Alpha value for start - this->alphaBitmap.fAlpha = ALPHA_VALUE_START; - - } + HRESULT hr; + + // Gets the handle of the parent and the graph + this->window = parent; + this->displayGraph = graph; + + if (this->window) { + // Hack to get module of the current code + TCHAR *modulePath = (TCHAR *) calloc(255, sizeof(TCHAR)); + GetModuleFileName((HINSTANCE)&__ImageBase, modulePath, 255); + HMODULE module = GetModuleHandle(modulePath); + delete[] modulePath; + if (!module) { + cout << "Failed to get current module"; + return; + } + + HBITMAP bitmap = LoadBitmap(module, MAKEINTRESOURCE(IDB_BITMAP_OVERLAY)); + if (!bitmap) { + cout << "Failed to load overlay bitmap" << endl; + return; + } + + RECT rect; + hr = GetWindowRect(this->window, &rect); + if (FAILED(hr)) { + cout << "Failed to get window size" << endl; + return; + } + + BITMAP bm; + HDC hdc = GetDC(this->window); + this->hdcBmp = CreateCompatibleDC(hdc); + ReleaseDC(this->window, hdc); + + GetObject(bitmap, sizeof(bm), &bm); + this->hbmOld= (HBITMAP) SelectObject(this->hdcBmp, bitmap); + + ZeroMemory(&this->alphaBitmap, sizeof(VMRALPHABITMAP)); + this->alphaBitmap.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY; + this->alphaBitmap.hdc = this->hdcBmp; + this->alphaBitmap.clrSrcKey = 0x00FF00FF; + // Source rectangle + this->alphaBitmap.rSrc.left = 0; + this->alphaBitmap.rSrc.top = 0; + this->alphaBitmap.rSrc.right = bm.bmWidth; + this->alphaBitmap.rSrc.bottom = bm.bmHeight; + // Destination rectangle + this->alphaBitmap.rDest.left = (rect.right - rect.left - bm.bmWidth) / 2.0; + this->alphaBitmap.rDest.top = (rect.bottom - rect.top - bm.bmHeight) / 2.0; + this->alphaBitmap.rDest.right = this->alphaBitmap.rDest.left + bm.bmWidth; + this->alphaBitmap.rDest.bottom = this->alphaBitmap.rDest.top + bm.bmHeight; + this->alphaBitmap.rDest.left /= (rect.right - rect.left); + this->alphaBitmap.rDest.top /= (rect.bottom - rect.top); + this->alphaBitmap.rDest.right /= (rect.right - rect.left); + this->alphaBitmap.rDest.bottom /= (rect.bottom - rect.top); + // Alpha value for start + this->alphaBitmap.fAlpha = ALPHA_VALUE_START; + + } } void DSDisplayOverlay::detach() { - // Clean up - DeleteObject(SelectObject(this->hdcBmp, this->hbmOld)); - DeleteDC(this->hdcBmp); - - this->hdcBmp = NULL; - this->hbmOld = NULL; - this->displayGraph = NULL; - this->window = NULL; + // Clean up + DeleteObject(SelectObject(this->hdcBmp, this->hbmOld)); + DeleteDC(this->hdcBmp); + + this->hdcBmp = NULL; + this->hbmOld = NULL; + this->displayGraph = NULL; + this->window = NULL; } void DSDisplayOverlay::show(int value) { - // Store the ticks to count down - this->ticks = value; + // Store the ticks to count down + this->ticks = value; - // Compute alpha value decrement - this->alphaStep = (this->ticks > 0) ? ((ALPHA_VALUE_START - ALPHA_VALUE_STOP) / this->ticks) : 0; - this->alphaBitmap.fAlpha = ALPHA_VALUE_START; + // Compute alpha value decrement + this->alphaStep = (this->ticks > 0) ? ((ALPHA_VALUE_START - ALPHA_VALUE_STOP) / this->ticks) : 0; + this->alphaBitmap.fAlpha = ALPHA_VALUE_START; - this->internalUpdate(); + this->internalUpdate(); } void DSDisplayOverlay::update() { - if (this->displayGraph && (this->ticks > 0)) - { - this->ticks--; + if (this->displayGraph && (this->ticks > 0)) { + this->ticks--; - // Be sure alpha is in 0.0 .. 1.0 range. - float value = this->alphaBitmap.fAlpha; - value -= this->alphaStep; - this->alphaBitmap.fAlpha = (value >= 0.0f) ? value : 0.0f; + // Be sure alpha is in 0.0 .. 1.0 range. + float value = this->alphaBitmap.fAlpha; + value -= this->alphaStep; + this->alphaBitmap.fAlpha = (value >= 0.0f) ? value : 0.0f; - this->internalUpdate(); - } + this->internalUpdate(); + } } void DSDisplayOverlay::internalUpdate() { - HRESULT hr; - - if (this->ticks > 0) - { - this->alphaBitmap.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY; - } - else - { - this->alphaBitmap.dwFlags = VMRBITMAP_DISABLE; - } - - hr = this->displayGraph->getMixerBitmap()->SetAlphaBitmap(&this->alphaBitmap); - if (FAILED(hr)) - { - cout << "Failed to mix overylay (" << hr << ")" << endl; - return; - } + HRESULT hr; + + if (this->ticks > 0) { + this->alphaBitmap.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY; + } + else { + this->alphaBitmap.dwFlags = VMRBITMAP_DISABLE; + } + + hr = this->displayGraph->getMixerBitmap()->SetAlphaBitmap(&this->alphaBitmap); + if (FAILED(hr)) { + cout << "Failed to mix overylay (" << hr << ")" << endl; + return; + } } #endif diff --git a/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR9.cxx b/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR9.cxx index 972945f..4504849 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR9.cxx +++ b/plugins/pluginDirectShow/internals/DSDisplayOverlay.VMR9.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -32,176 +32,165 @@ using namespace std; DSDisplayOverlay::DSDisplayOverlay() { - this->window = NULL; - this->direct3DDevice = NULL; - this->direct3DSurface = NULL; - - this->direct3D = Direct3DCreate9(D3D_SDK_VERSION); - if (!this->direct3D) - { - cout << "Cannot create Direct3D environment" << endl; - return; - } + this->window = NULL; + this->direct3DDevice = NULL; + this->direct3DSurface = NULL; + + this->direct3D = Direct3DCreate9(D3D_SDK_VERSION); + if (!this->direct3D) { + cout << "Cannot create Direct3D environment" << endl; + return; + } } DSDisplayOverlay::~DSDisplayOverlay() { - SAFE_RELEASE(this->direct3D); + SAFE_RELEASE(this->direct3D); } void DSDisplayOverlay::attach(HWND parent, DSDisplayGraph *graph) { - HRESULT hr; - - // Gets the handle of the parent and the graph - this->window = parent; - this->displayGraph = graph; - - if (this->window) - { - D3DPRESENT_PARAMETERS d3dpp; - ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; - - hr = this->direct3D->CreateDevice( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - this->window, - D3DCREATE_SOFTWARE_VERTEXPROCESSING, - &d3dpp, - &this->direct3DDevice); - if (FAILED(hr)) - { - cout << "Cannot create Direct3D device" << endl; - return; - } - - ZeroMemory(&this->overlayInfo, sizeof(D3DXIMAGE_INFO)); - hr = D3DXGetImageInfoFromFile(FILENAME, &this->overlayInfo); - if (FAILED(hr)) - { - cout << "Cannot stat overlay file" << endl; - return; - } - - hr = this->direct3DDevice->CreateOffscreenPlainSurface( - this->overlayInfo.Width, - this->overlayInfo.Height, - D3DFMT_A8R8G8B8, - D3DPOOL_SYSTEMMEM, - &this->direct3DSurface, - NULL); - if (FAILED(hr)) - { - cout << "Cannot create Direct3D surface" << endl; - return; - } - - D3DCOLOR alphaKey = 0xFF000000; - - hr = D3DXLoadSurfaceFromFile(this->direct3DSurface, - NULL, - NULL, - FILENAME, - NULL, - D3DX_FILTER_NONE, - alphaKey, - &this->overlayInfo); - if (FAILED(hr)) - { - cout << "Cannot load overlay file" << endl; - return; - } - - D3DVIEWPORT9 viewport; - ZeroMemory(&viewport, sizeof(D3DVIEWPORT9)); - - hr= this->direct3DDevice->GetViewport(&viewport); - if (FAILED(hr)) - { - cout << "Cannot get view port" << endl; - return; - } - - ZeroMemory(&this->alphaBitmap, sizeof(VMR9AlphaBitmap)); - this->alphaBitmap.dwFlags = VMR9AlphaBitmap_EntireDDS; - this->alphaBitmap.hdc = NULL; - this->alphaBitmap.pDDS = this->direct3DSurface; - // Source rectangle - this->alphaBitmap.rSrc.left = 0; - this->alphaBitmap.rSrc.top = 0; - this->alphaBitmap.rSrc.right = this->overlayInfo.Width; - this->alphaBitmap.rSrc.bottom = this->overlayInfo.Height; - // Destination rectangle - this->alphaBitmap.rDest.left = (viewport.Width - this->overlayInfo.Width) / 2.0; - this->alphaBitmap.rDest.top = (viewport.Height - this->overlayInfo.Height) / 2.0; - this->alphaBitmap.rDest.right = this->alphaBitmap.rDest.left + this->overlayInfo.Width; - this->alphaBitmap.rDest.bottom = this->alphaBitmap.rDest.top + this->overlayInfo.Height; - this->alphaBitmap.rDest.left /= viewport.Width; - this->alphaBitmap.rDest.top /= viewport.Height; - this->alphaBitmap.rDest.right /= viewport.Width; - this->alphaBitmap.rDest.bottom /= viewport.Height; - // Alpha value for start - this->alphaBitmap.fAlpha = ALPHA_VALUE_START; - } + HRESULT hr; + + // Gets the handle of the parent and the graph + this->window = parent; + this->displayGraph = graph; + + if (this->window) { + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; + + hr = this->direct3D->CreateDevice( + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + this->window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, + &this->direct3DDevice); + if (FAILED(hr)) { + cout << "Cannot create Direct3D device" << endl; + return; + } + + ZeroMemory(&this->overlayInfo, sizeof(D3DXIMAGE_INFO)); + hr = D3DXGetImageInfoFromFile(FILENAME, &this->overlayInfo); + if (FAILED(hr)) { + cout << "Cannot stat overlay file" << endl; + return; + } + + hr = this->direct3DDevice->CreateOffscreenPlainSurface( + this->overlayInfo.Width, + this->overlayInfo.Height, + D3DFMT_A8R8G8B8, + D3DPOOL_SYSTEMMEM, + &this->direct3DSurface, + NULL); + if (FAILED(hr)) { + cout << "Cannot create Direct3D surface" << endl; + return; + } + + D3DCOLOR alphaKey = 0xFF000000; + + hr = D3DXLoadSurfaceFromFile(this->direct3DSurface, + NULL, + NULL, + FILENAME, + NULL, + D3DX_FILTER_NONE, + alphaKey, + &this->overlayInfo); + if (FAILED(hr)) { + cout << "Cannot load overlay file" << endl; + return; + } + + D3DVIEWPORT9 viewport; + ZeroMemory(&viewport, sizeof(D3DVIEWPORT9)); + + hr= this->direct3DDevice->GetViewport(&viewport); + if (FAILED(hr)) { + cout << "Cannot get view port" << endl; + return; + } + + ZeroMemory(&this->alphaBitmap, sizeof(VMR9AlphaBitmap)); + this->alphaBitmap.dwFlags = VMR9AlphaBitmap_EntireDDS; + this->alphaBitmap.hdc = NULL; + this->alphaBitmap.pDDS = this->direct3DSurface; + // Source rectangle + this->alphaBitmap.rSrc.left = 0; + this->alphaBitmap.rSrc.top = 0; + this->alphaBitmap.rSrc.right = this->overlayInfo.Width; + this->alphaBitmap.rSrc.bottom = this->overlayInfo.Height; + // Destination rectangle + this->alphaBitmap.rDest.left = (viewport.Width - this->overlayInfo.Width) / 2.0; + this->alphaBitmap.rDest.top = (viewport.Height - this->overlayInfo.Height) / 2.0; + this->alphaBitmap.rDest.right = this->alphaBitmap.rDest.left + this->overlayInfo.Width; + this->alphaBitmap.rDest.bottom = this->alphaBitmap.rDest.top + this->overlayInfo.Height; + this->alphaBitmap.rDest.left /= viewport.Width; + this->alphaBitmap.rDest.top /= viewport.Height; + this->alphaBitmap.rDest.right /= viewport.Width; + this->alphaBitmap.rDest.bottom /= viewport.Height; + // Alpha value for start + this->alphaBitmap.fAlpha = ALPHA_VALUE_START; + } } void DSDisplayOverlay::detach() { - SAFE_RELEASE(this->direct3DSurface); - SAFE_RELEASE(this->direct3DDevice); + SAFE_RELEASE(this->direct3DSurface); + SAFE_RELEASE(this->direct3DDevice); - this->displayGraph = NULL; - this->window = NULL; + this->displayGraph = NULL; + this->window = NULL; } void DSDisplayOverlay::show(int value) { - // Store the ticks to count down - this->ticks = value; + // Store the ticks to count down + this->ticks = value; - // Compute alpha value decrement - this->alphaStep = (this->ticks > 0) ? ((ALPHA_VALUE_START - ALPHA_VALUE_STOP) / this->ticks) : 0; - this->alphaBitmap.fAlpha = ALPHA_VALUE_START; + // Compute alpha value decrement + this->alphaStep = (this->ticks > 0) ? ((ALPHA_VALUE_START - ALPHA_VALUE_STOP) / this->ticks) : 0; + this->alphaBitmap.fAlpha = ALPHA_VALUE_START; - this->internalUpdate(); + this->internalUpdate(); } void DSDisplayOverlay::update() { - if (this->displayGraph && (this->ticks > 0)) - { - this->ticks--; + if (this->displayGraph && (this->ticks > 0)) { + this->ticks--; - // Be sure alpha is in 0.0 .. 1.0 range. - float value = this->alphaBitmap.fAlpha; - value -= this->alphaStep; - this->alphaBitmap.fAlpha = (value >= 0.0f) ? value : 0.0f; + // Be sure alpha is in 0.0 .. 1.0 range. + float value = this->alphaBitmap.fAlpha; + value -= this->alphaStep; + this->alphaBitmap.fAlpha = (value >= 0.0f) ? value : 0.0f; - this->internalUpdate(); - } + this->internalUpdate(); + } } void DSDisplayOverlay::internalUpdate() { - HRESULT hr; - - if (this->ticks > 0) - { - this->alphaBitmap.dwFlags = VMR9AlphaBitmap_EntireDDS; - } - else - { - this->alphaBitmap.dwFlags = VMR9AlphaBitmap_Disable; - } - - hr = this->displayGraph->getMixerBitmap()->SetAlphaBitmap(&this->alphaBitmap); - if (FAILED(hr)) - { - cout << "Failed to mix overylay (" << hr << ")" << endl; - return; - } + HRESULT hr; + + if (this->ticks > 0) { + this->alphaBitmap.dwFlags = VMR9AlphaBitmap_EntireDDS; + } + else { + this->alphaBitmap.dwFlags = VMR9AlphaBitmap_Disable; + } + + hr = this->displayGraph->getMixerBitmap()->SetAlphaBitmap(&this->alphaBitmap); + if (FAILED(hr)) { + cout << "Failed to mix overylay (" << hr << ")" << endl; + return; + } } #endif diff --git a/plugins/pluginDirectShow/internals/DSDisplayOverlay.cxx b/plugins/pluginDirectShow/internals/DSDisplayOverlay.cxx index eb355c4..7c5463b 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayOverlay.cxx +++ b/plugins/pluginDirectShow/internals/DSDisplayOverlay.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -34,34 +34,33 @@ DSDisplayOverlay::~DSDisplayOverlay() void DSDisplayOverlay::attach(HWND parent, DSDisplayGraph *graph) { - this->displayGraph = graph; + this->displayGraph = graph; } void DSDisplayOverlay::detach() { - this->displayGraph = NULL; + this->displayGraph = NULL; } void DSDisplayOverlay::show(int value) { - // Store the ticks to count down - this->ticks = value; + // Store the ticks to count down + this->ticks = value; - this->internalUpdate(); + this->internalUpdate(); } void DSDisplayOverlay::update() { - if (this->displayGraph && (this->ticks > 0)) - { - this->ticks--; - this->internalUpdate(); - } + if (this->displayGraph && (this->ticks > 0)) { + this->ticks--; + this->internalUpdate(); + } } void DSDisplayOverlay::internalUpdate() { - this->displayGraph->getSourceFilter()->showOverlay(this->ticks); + this->displayGraph->getSourceFilter()->showOverlay(this->ticks); } #endif diff --git a/plugins/pluginDirectShow/internals/DSDisplayOverlay.h b/plugins/pluginDirectShow/internals/DSDisplayOverlay.h index 0db887d..69ed6a3 100755 --- a/plugins/pluginDirectShow/internals/DSDisplayOverlay.h +++ b/plugins/pluginDirectShow/internals/DSDisplayOverlay.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -32,36 +32,36 @@ class DSDisplayGraph; class DSDisplayOverlay { public: - DSDisplayOverlay(); - virtual ~DSDisplayOverlay(); + DSDisplayOverlay(); + virtual ~DSDisplayOverlay(); - void attach(HWND parent, DSDisplayGraph *graph); - void detach(); + void attach(HWND parent, DSDisplayGraph *graph); + void detach(); - void show(int value); - void update(); + void show(int value); + void update(); private: - void internalUpdate(); + void internalUpdate(); private: - HWND window; + HWND window; - DSDisplayGraph *displayGraph; - int ticks; + DSDisplayGraph *displayGraph; + int ticks; #if defined(VMR) - HDC hdcBmp; - HBITMAP hbmOld; - VMRALPHABITMAP alphaBitmap; - float alphaStep; + HDC hdcBmp; + HBITMAP hbmOld; + VMRALPHABITMAP alphaBitmap; + float alphaStep; #elif defined(VMR9) || defined(VMR9_WINDOWLESS) - IDirect3D9 *direct3D; - IDirect3DDevice9 *direct3DDevice; - IDirect3DSurface9 *direct3DSurface; - D3DXIMAGE_INFO overlayInfo; - VMR9AlphaBitmap alphaBitmap; - float alphaStep; + IDirect3D9 *direct3D; + IDirect3DDevice9 *direct3DDevice; + IDirect3DSurface9 *direct3DSurface; + D3DXIMAGE_INFO overlayInfo; + VMR9AlphaBitmap alphaBitmap; + float alphaStep; #endif }; diff --git a/plugins/pluginDirectShow/internals/DSFrameRateFilter.cxx b/plugins/pluginDirectShow/internals/DSFrameRateFilter.cxx index cbf2a0a..c44ba03 100755 --- a/plugins/pluginDirectShow/internals/DSFrameRateFilter.cxx +++ b/plugins/pluginDirectShow/internals/DSFrameRateFilter.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,20 +26,20 @@ using namespace std; #define FPS_OUTPUT 5 // {7F9F08CF-139F-40b2-A283-01C4EC26A452} -TDSHOW_DEFINE_GUID(CLSID_DSFrameRateFilter, -0x7f9f08cf, 0x139f, 0x40b2, 0xa2, 0x83, 0x1, 0xc4, 0xec, 0x26, 0xa4, 0x52); +TDSHOW_DEFINE_GUID(CLSID_DSFrameRateFilter, + 0x7f9f08cf, 0x139f, 0x40b2, 0xa2, 0x83, 0x1, 0xc4, 0xec, 0x26, 0xa4, 0x52); DSFrameRateFilter::DSFrameRateFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) -:CTransInPlaceFilter (tszName, punk, CLSID_DSFrameRateFilter, phr) + :CTransInPlaceFilter (tszName, punk, CLSID_DSFrameRateFilter, phr) { - this->m_rtFrameLength = (10000000)/FPS_OUTPUT; + this->m_rtFrameLength = (10000000)/FPS_OUTPUT; - this->m_inputFps = FPS_INPUT; - this->m_outputFps = FPS_OUTPUT; + this->m_inputFps = FPS_INPUT; + this->m_outputFps = FPS_OUTPUT; - this->m_iFrameNumber = 0; - this->m_progress = 0; - this->m_bProcessFrame = true; + this->m_iFrameNumber = 0; + this->m_progress = 0; + this->m_bProcessFrame = true; } DSFrameRateFilter::~DSFrameRateFilter() @@ -48,73 +48,74 @@ DSFrameRateFilter::~DSFrameRateFilter() HRESULT DSFrameRateFilter::SetFps(int inputFps, int outputFps) { - if(inputFps <= 0 || outputFps <= 0) - { - return E_FAIL; - } - - // Stop prcessing - this->m_bProcessFrame = false; - - if (inputFps < outputFps) { - this->m_inputFps = this->m_outputFps = inputFps; - } - else { - this->m_outputFps = outputFps; - this->m_inputFps = inputFps; - } - - // Restart processing - this->m_iFrameNumber = 0; - this->m_progress = 0; - this->m_bProcessFrame = true; - - return S_OK; + if(inputFps <= 0 || outputFps <= 0) { + return E_FAIL; + } + + // Stop prcessing + this->m_bProcessFrame = false; + + if (inputFps < outputFps) { + this->m_inputFps = this->m_outputFps = inputFps; + } + else { + this->m_outputFps = outputFps; + this->m_inputFps = inputFps; + } + + // Restart processing + this->m_iFrameNumber = 0; + this->m_progress = 0; + this->m_bProcessFrame = true; + + return S_OK; } HRESULT DSFrameRateFilter::Transform(IMediaSample *pSample) -{ - if(!this->m_bProcessFrame) return S_FALSE; +{ + if(!this->m_bProcessFrame) { + return S_FALSE; + } - CheckPointer(pSample, E_POINTER); + CheckPointer(pSample, E_POINTER); - HRESULT hr = S_OK; - HRESULT ret = S_FALSE; + HRESULT hr = S_OK; + HRESULT ret = S_FALSE; - pSample->SetTime(NULL, NULL); + pSample->SetTime(NULL, NULL); - // Drop frame? - if (this->m_iFrameNumber == 0) { - ret = S_OK; - } - else if (this->m_progress >= this->m_inputFps) { - this->m_progress -= this->m_inputFps; - ret = S_OK; - } + // Drop frame? + if (this->m_iFrameNumber == 0) { + ret = S_OK; + } + else if (this->m_progress >= this->m_inputFps) { + this->m_progress -= this->m_inputFps; + ret = S_OK; + } - // Mark frame as accepted - if (ret == S_OK) { - // Set TRUE on every sample for uncompressed frames - pSample->SetSyncPoint(TRUE); - } + // Mark frame as accepted + if (ret == S_OK) { + // Set TRUE on every sample for uncompressed frames + pSample->SetSyncPoint(TRUE); + } - this->m_progress += this->m_outputFps; - this->m_iFrameNumber++; + this->m_progress += this->m_outputFps; + this->m_iFrameNumber++; - return ret; + return ret; } HRESULT DSFrameRateFilter::CheckInputType(const CMediaType* mtIn) -{ - return S_OK; +{ + return S_OK; } //Implement CreateInstance for your filter object. Typically, CreateInstance calls the constructor of your filter clas CUnknown * WINAPI DSFrameRateFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr) { - DSFrameRateFilter *pNewObject = new DSFrameRateFilter(_T("Tdshow DirectShow Framerate Limiter Filter."), punk, phr ); - if (pNewObject == NULL) { - *phr = E_OUTOFMEMORY; - } - return pNewObject; -} + DSFrameRateFilter *pNewObject = new DSFrameRateFilter(_T("Tdshow DirectShow Framerate Limiter Filter."), punk, phr ); + if (pNewObject == NULL) { + *phr = E_OUTOFMEMORY; + } + return pNewObject; +} diff --git a/plugins/pluginDirectShow/internals/DSFrameRateFilter.h b/plugins/pluginDirectShow/internals/DSFrameRateFilter.h index 9f2296e..eff2bfb 100755 --- a/plugins/pluginDirectShow/internals/DSFrameRateFilter.h +++ b/plugins/pluginDirectShow/internals/DSFrameRateFilter.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,39 +26,39 @@ class DSFrameRateFilter : public CTransInPlaceFilter { public: - DSFrameRateFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr); - ~DSFrameRateFilter(void); + DSFrameRateFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr); + ~DSFrameRateFilter(void); public: - HRESULT Transform(IMediaSample *pSample); + HRESULT Transform(IMediaSample *pSample); HRESULT CheckInputType(const CMediaType* mtIn); public: - /** - * \def SetFps - * \brief fps1 define source . - */ - HRESULT SetFps(int inputFps, int outputFps); + /** + * \def SetFps + * \brief fps1 define source . + */ + HRESULT SetFps(int inputFps, int outputFps); static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr); DECLARE_IUNKNOWN; - /*STDMETHODIMP_(ULONG) NonDelegatingRelease() - { - if(InterlockedDecrement(&m_cRef) == 0) - { - delete this; - return 0; - } - return m_cRef; - }*/ + /*STDMETHODIMP_(ULONG) NonDelegatingRelease() + { + if(InterlockedDecrement(&m_cRef) == 0) + { + delete this; + return 0; + } + return m_cRef; + }*/ private: - int m_progress; - int m_inputFps, m_outputFps; - bool m_bProcessFrame; - REFERENCE_TIME m_rtFrameLength; // UNITS/fps - LONGLONG m_iFrameNumber; + int m_progress; + int m_inputFps, m_outputFps; + bool m_bProcessFrame; + REFERENCE_TIME m_rtFrameLength; // UNITS/fps + LONGLONG m_iFrameNumber; }; #endif ////DSFrameRateFilter_H
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/DSGrabber.cxx b/plugins/pluginDirectShow/internals/DSGrabber.cxx index e4dc3a7..18df2a3 100755 --- a/plugins/pluginDirectShow/internals/DSGrabber.cxx +++ b/plugins/pluginDirectShow/internals/DSGrabber.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -33,260 +33,257 @@ using namespace std; DSGrabber::DSGrabber(HRESULT *hr, BOOL _screenCast) -: mutex_buffer(NULL), preview(NULL) -, screenCast(_screenCast) + : mutex_buffer(NULL), preview(NULL) + , screenCast(_screenCast) { #if defined(_WIN32_WCE) - assert(!screenCast); - this->graph = new DSCaptureGraph(this, hr); - CHECK_HR((*hr)); + assert(!screenCast); + this->graph = new DSCaptureGraph(this, hr); + CHECK_HR((*hr)); #else - this->graph = screenCast ? dynamic_cast<DSBaseCaptureGraph*>(new DSScreenCastGraph(this, hr)) : dynamic_cast<DSBaseCaptureGraph*>(new DSCaptureGraph(this, hr)); - CHECK_HR((*hr)); - this->preview = new DSDisplay(hr); + this->graph = screenCast ? dynamic_cast<DSBaseCaptureGraph*>(new DSScreenCastGraph(this, hr)) : dynamic_cast<DSBaseCaptureGraph*>(new DSCaptureGraph(this, hr)); + CHECK_HR((*hr)); + this->preview = new DSDisplay(hr); #endif - // Init the bitmap info header with default values - memset(&(this->bitmapInfo), 0, sizeof(BITMAPINFOHEADER)); - this->bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); - this->bitmapInfo.biWidth = 352; - this->bitmapInfo.biHeight = 288; - this->bitmapInfo.biPlanes = 1; - this->bitmapInfo.biBitCount = 24; - this->bitmapInfo.biCompression = 0; - this->bitmapInfo.biXPelsPerMeter = 0; - this->bitmapInfo.biYPelsPerMeter = 0; - this->bitmapInfo.biClrUsed = 0; - this->bitmapInfo.biClrImportant = 0; - - this->plugin_cb = NULL; - this->buffer = NULL; - this->mutex_buffer = tsk_mutex_create(); - -bail: ; + // Init the bitmap info header with default values + memset(&(this->bitmapInfo), 0, sizeof(BITMAPINFOHEADER)); + this->bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); + this->bitmapInfo.biWidth = 352; + this->bitmapInfo.biHeight = 288; + this->bitmapInfo.biPlanes = 1; + this->bitmapInfo.biBitCount = 24; + this->bitmapInfo.biCompression = 0; + this->bitmapInfo.biXPelsPerMeter = 0; + this->bitmapInfo.biYPelsPerMeter = 0; + this->bitmapInfo.biClrUsed = 0; + this->bitmapInfo.biClrImportant = 0; + + this->plugin_cb = NULL; + this->buffer = NULL; + this->mutex_buffer = tsk_mutex_create(); + +bail: + ; } DSGrabber::~DSGrabber() { - SAFE_DELETE_PTR ( this->graph ); - SAFE_DELETE_PTR ( this->preview ); - SAFE_DELETE_ARRAY ( this->buffer ); - tsk_mutex_destroy(&this->mutex_buffer); + SAFE_DELETE_PTR ( this->graph ); + SAFE_DELETE_PTR ( this->preview ); + SAFE_DELETE_ARRAY ( this->buffer ); + tsk_mutex_destroy(&this->mutex_buffer); } void DSGrabber::setCaptureDevice(const std::string &devicePath) { - this->graph->setSource(devicePath); + this->graph->setSource(devicePath); } void DSGrabber::setCallback(tmedia_producer_enc_cb_f callback, const void* callback_data) { - this->plugin_cb = callback; - this->plugin_cb_data = callback_data; + this->plugin_cb = callback; + this->plugin_cb_data = callback_data; } void DSGrabber::start() { - if(this->graph->isPaused()){ - this->graph->start(); - this->preview->start(); - return; - } - - if (!this->graph->isRunning()){ - first_buffer = true; - - if(this->preview){ - this->preview->start(); - } - this->graph->connect(); - this->graph->start(); - } + if(this->graph->isPaused()) { + this->graph->start(); + this->preview->start(); + return; + } + + if (!this->graph->isRunning()) { + first_buffer = true; + + if(this->preview) { + this->preview->start(); + } + this->graph->connect(); + this->graph->start(); + } } void DSGrabber::pause() { - if(this->graph && this->graph->isRunning()){ - this->graph->pause(); - this->preview->pause(); - } + if(this->graph && this->graph->isRunning()) { + this->graph->pause(); + this->preview->pause(); + } } void DSGrabber::stop() { - if (this->graph->isRunning()){ - if(this->preview){ - this->preview->stop(); - } - this->graph->stop(); - this->graph->disconnect(); - } + if (this->graph->isRunning()) { + if(this->preview) { + this->preview->stop(); + } + this->graph->stop(); + this->graph->disconnect(); + } } bool DSGrabber::setCaptureParameters(int w, int h, int f) { - tsk_mutex_lock(this->mutex_buffer); - - // Store the framerate - this->fps = f; - this->width = w; - this->height = h; - - // Store the required dimensions - this->bitmapInfo.biWidth = this->width; - this->bitmapInfo.biHeight = this->height; - this->bitmapInfo.biBitCount = 24; - this->bitmapInfo.biSizeImage = (this->width * this->height * 3); - - // Change the intermediate buffer - SAFE_DELETE_ARRAY ( this->buffer ); - this->buffer = new BYTE[this->bitmapInfo.biSizeImage]; - memset(this->buffer,0,this->bitmapInfo.biSizeImage); - - // Find closest matching format to drive the source filter - DSCaptureFormat *fmt = NULL; - int score = 0; - std::vector<DSCaptureFormat> *formats = this->graph->getFormats(); - std::vector<DSCaptureFormat>::iterator iter; - std::vector<DSCaptureFormat>::iterator last = formats->end(); - for(iter = formats->begin(); iter != last; iter++){ - int value = (*iter).getMatchScore(this->width, this->height); - if (value > score || !fmt){ - score = value; - fmt = &(*iter); - } - } - - // Setup source filter in the graph - HRESULT hr = this->graph->setParameters(fmt, this->fps); - // Set preview parameters - if(this->preview){ - this->preview->setFps(this->fps); - this->preview->setSize(this->width, this->height); - } - - tsk_mutex_unlock(this->mutex_buffer); - - return SUCCEEDED(hr); + tsk_mutex_lock(this->mutex_buffer); + + // Store the framerate + this->fps = f; + this->width = w; + this->height = h; + + // Store the required dimensions + this->bitmapInfo.biWidth = this->width; + this->bitmapInfo.biHeight = this->height; + this->bitmapInfo.biBitCount = 24; + this->bitmapInfo.biSizeImage = (this->width * this->height * 3); + + // Change the intermediate buffer + SAFE_DELETE_ARRAY ( this->buffer ); + this->buffer = new BYTE[this->bitmapInfo.biSizeImage]; + memset(this->buffer,0,this->bitmapInfo.biSizeImage); + + // Find closest matching format to drive the source filter + DSCaptureFormat *fmt = NULL; + int score = 0; + std::vector<DSCaptureFormat> *formats = this->graph->getFormats(); + std::vector<DSCaptureFormat>::iterator iter; + std::vector<DSCaptureFormat>::iterator last = formats->end(); + for(iter = formats->begin(); iter != last; iter++) { + int value = (*iter).getMatchScore(this->width, this->height); + if (value > score || !fmt) { + score = value; + fmt = &(*iter); + } + } + + // Setup source filter in the graph + HRESULT hr = this->graph->setParameters(fmt, this->fps); + // Set preview parameters + if(this->preview) { + this->preview->setFps(this->fps); + this->preview->setSize(this->width, this->height); + } + + tsk_mutex_unlock(this->mutex_buffer); + + return SUCCEEDED(hr); } void DSGrabber::setPluginFirefox(bool value) { - if(this->preview){ - this->preview->setPluginFirefox(value); - } + if(this->preview) { + this->preview->setPluginFirefox(value); + } } bool DSGrabber::setCaptureParameters(int format, int f) { - int w, h; - // Get size from the format - VIDEOFORMAT_TO_SIZE(format, w, h); - return this->setCaptureParameters(w, h, f); + int w, h; + // Get size from the format + VIDEOFORMAT_TO_SIZE(format, w, h); + return this->setCaptureParameters(w, h, f); } int DSGrabber::getFramerate() { - return this->fps; + return this->fps; } HRESULT DSGrabber::getConnectedMediaType(AM_MEDIA_TYPE *mediaType) { - if (!this->graph || !mediaType) { - return E_INVALIDARG; - } - return this->graph->getConnectedMediaType(mediaType); + if (!this->graph || !mediaType) { + return E_INVALIDARG; + } + return this->graph->getConnectedMediaType(mediaType); } HRESULT DSGrabber::SampleCB(double SampleTime, IMediaSample *pSample) { - return S_OK; + return S_OK; } HRESULT DSGrabber::BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) -{ - HRESULT hr; - - tsk_mutex_lock(this->mutex_buffer); - - AM_MEDIA_TYPE mediaType; - hr = this->graph->getConnectedMediaType(&mediaType); - if (FAILED(hr) || !this->buffer){ - return hr; - } - - if(first_buffer){ - first_buffer = false; - - tsk_mutex_unlock(this->mutex_buffer); - return hr; - } - - // Examine the format block. - if ((mediaType.formattype == FORMAT_VideoInfo) && (mediaType.cbFormat >= sizeof(VIDEOINFOHEADER)) && (mediaType.pbFormat != NULL) ) - { - VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER *>(mediaType.pbFormat); - BITMAPINFOHEADER* bih = &pVih->bmiHeader; - - //int framerate = pVih->AvgTimePerFrame; - if( (bih->biHeight == this->bitmapInfo.biHeight) && (bih->biWidth == this->bitmapInfo.biWidth) && (bih->biBitCount == this->bitmapInfo.biBitCount) ) - { - memmove(this->buffer, pBuffer, this->bitmapInfo.biSizeImage); - } - else - { - ResizeRGB( - bih, - (const unsigned char *) pBuffer, - &this->bitmapInfo, - (unsigned char *) this->buffer, - this->width, - this->height); - } - - // for the network - if(this->plugin_cb){ - this->plugin_cb(this->plugin_cb_data, this->buffer, (this->width*this->height*3)); - } - - // for the preview - if(this->preview){ - this->preview->handleVideoFrame(this->buffer, this->width, this->height); - } - } - - // Free the format +{ + HRESULT hr; + + tsk_mutex_lock(this->mutex_buffer); + + AM_MEDIA_TYPE mediaType; + hr = this->graph->getConnectedMediaType(&mediaType); + if (FAILED(hr) || !this->buffer) { + return hr; + } + + if(first_buffer) { + first_buffer = false; + + tsk_mutex_unlock(this->mutex_buffer); + return hr; + } + + // Examine the format block. + if ((mediaType.formattype == FORMAT_VideoInfo) && (mediaType.cbFormat >= sizeof(VIDEOINFOHEADER)) && (mediaType.pbFormat != NULL) ) { + VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER *>(mediaType.pbFormat); + BITMAPINFOHEADER* bih = &pVih->bmiHeader; + + //int framerate = pVih->AvgTimePerFrame; + if( (bih->biHeight == this->bitmapInfo.biHeight) && (bih->biWidth == this->bitmapInfo.biWidth) && (bih->biBitCount == this->bitmapInfo.biBitCount) ) { + memmove(this->buffer, pBuffer, this->bitmapInfo.biSizeImage); + } + else { + ResizeRGB( + bih, + (const unsigned char *) pBuffer, + &this->bitmapInfo, + (unsigned char *) this->buffer, + this->width, + this->height); + } + + // for the network + if(this->plugin_cb) { + this->plugin_cb(this->plugin_cb_data, this->buffer, (this->width*this->height*3)); + } + + // for the preview + if(this->preview) { + this->preview->handleVideoFrame(this->buffer, this->width, this->height); + } + } + + // Free the format #ifdef _WIN32_WCE - // Nothing had been allocated + // Nothing had been allocated #else - FreeMediaType(mediaType); + FreeMediaType(mediaType); #endif - tsk_mutex_unlock(this->mutex_buffer); + tsk_mutex_unlock(this->mutex_buffer); - return hr; + return hr; } HRESULT DSGrabber::QueryInterface(REFIID iid, LPVOID *ppv) { #ifdef _WIN32_WCE - assert(1==0); + assert(1==0); #else - if( iid == IID_ISampleGrabberCB || iid == IID_IUnknown ) - { - *ppv = (void *) static_cast<ISampleGrabberCB*>(this); - return NOERROR; - } + if( iid == IID_ISampleGrabberCB || iid == IID_IUnknown ) { + *ppv = (void *) static_cast<ISampleGrabberCB*>(this); + return NOERROR; + } #endif - return E_NOINTERFACE; + return E_NOINTERFACE; } ULONG DSGrabber::AddRef() { - return 2; + return 2; } ULONG DSGrabber::Release() { - return 1; + return 1; }
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/DSGrabber.h b/plugins/pluginDirectShow/internals/DSGrabber.h index 64cde75..3445fb3 100755 --- a/plugins/pluginDirectShow/internals/DSGrabber.h +++ b/plugins/pluginDirectShow/internals/DSGrabber.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -36,57 +36,57 @@ class DSDisplay; class DSGrabber : public #if defined(_WIN32_WCE) - DSISampleGrabberCB + DSISampleGrabberCB #else - ISampleGrabberCB + ISampleGrabberCB #endif { public: - DSGrabber(HRESULT *hr, BOOL screenCast); - virtual ~DSGrabber(); + DSGrabber(HRESULT *hr, BOOL screenCast); + virtual ~DSGrabber(); - void setCallback(tmedia_producer_enc_cb_f callback, const void* callback_data); - void setCaptureDevice(const std::string &devicePath); + void setCallback(tmedia_producer_enc_cb_f callback, const void* callback_data); + void setCaptureDevice(const std::string &devicePath); - virtual void start(); - virtual void pause(); - virtual void stop(); + virtual void start(); + virtual void pause(); + virtual void stop(); - virtual bool setCaptureParameters(int format, int f); - virtual bool setCaptureParameters(int w, int h, int f); + virtual bool setCaptureParameters(int format, int f); + virtual bool setCaptureParameters(int w, int h, int f); - virtual void setPluginFirefox(bool value); + virtual void setPluginFirefox(bool value); - virtual int getFramerate(); - virtual HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); + virtual int getFramerate(); + virtual HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); - virtual HRESULT STDMETHODCALLTYPE SampleCB(double SampleTime, IMediaSample *pSample); + virtual HRESULT STDMETHODCALLTYPE SampleCB(double SampleTime, IMediaSample *pSample); virtual HRESULT STDMETHODCALLTYPE BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen); - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); - virtual ULONG STDMETHODCALLTYPE AddRef(); - virtual ULONG STDMETHODCALLTYPE Release(); + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); - DSDisplay *preview; + DSDisplay *preview; private: - int width; - int height; - int fps; + int width; + int height; + int fps; - DSBaseCaptureGraph *graph; + DSBaseCaptureGraph *graph; - //VideoFrame *currentFrame; - BITMAPINFOHEADER bitmapInfo; - BYTE *buffer; + //VideoFrame *currentFrame; + BITMAPINFOHEADER bitmapInfo; + BYTE *buffer; - tsk_mutex_handle_t *mutex_buffer; + tsk_mutex_handle_t *mutex_buffer; - BOOL first_buffer; - BOOL screenCast; + BOOL first_buffer; + BOOL screenCast; - const void* plugin_cb_data; - tmedia_producer_enc_cb_f plugin_cb; + const void* plugin_cb_data; + tmedia_producer_enc_cb_f plugin_cb; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSOutputFilter.cxx b/plugins/pluginDirectShow/internals/DSOutputFilter.cxx index ab5aa0f..7efbcc6 100755 --- a/plugins/pluginDirectShow/internals/DSOutputFilter.cxx +++ b/plugins/pluginDirectShow/internals/DSOutputFilter.cxx @@ -1,18 +1,18 @@ /* * Copyright (C) 2010-2011 Mamadou DIOP. -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. * @@ -23,91 +23,92 @@ #include "tsk_memory.h" -DSOutputFilter::DSOutputFilter(LPUNKNOWN pUnk, HRESULT *phr) -: CSource(_T("TDSHOW_OUTPUT"), pUnk, CLSID_TdshowOutputFilter) +DSOutputFilter::DSOutputFilter(LPUNKNOWN pUnk, HRESULT *phr) + : CSource(_T("TDSHOW_OUTPUT"), pUnk, CLSID_TdshowOutputFilter) { #if !(defined(_WIN32_WCE) && defined(_DEBUG)) CAutoLock cAutoLock(&m_cStateLock); #endif - // Add one source stream (output pin)! - this->outputStream = new DSOutputStream(phr, this, _T("Out")); + // Add one source stream (output pin)! + this->outputStream = new DSOutputStream(phr, this, _T("Out")); } DSOutputFilter::~DSOutputFilter() { - //SAFE_RELEASE(this->outputStream); + //SAFE_RELEASE(this->outputStream); } void DSOutputFilter::setBuffer(void *pointer, int size) { - this->outputStream->lockBuffer(); - if(pointer && size){ - if(this->outputStream->buffer_size != size){ - if((this->outputStream->buffer = tsk_realloc(this->outputStream->buffer, size))){ - this->outputStream->buffer_size = size; - } - else goto done; - } - memcpy(this->outputStream->buffer, pointer, size); - } + this->outputStream->lockBuffer(); + if(pointer && size) { + if(this->outputStream->buffer_size != size) { + if((this->outputStream->buffer = tsk_realloc(this->outputStream->buffer, size))) { + this->outputStream->buffer_size = size; + } + else { + goto done; + } + } + memcpy(this->outputStream->buffer, pointer, size); + } done: - this->outputStream->unlockBuffer(); + this->outputStream->unlockBuffer(); } void DSOutputFilter::getMediaType(AM_MEDIA_TYPE* &pmt) { - //if(pmt) - //{ - // memcpy(pmt, &this->outputStream->pmt, sizeof(AM_MEDIA_TYPE)); - //} + //if(pmt) + //{ + // memcpy(pmt, &this->outputStream->pmt, sizeof(AM_MEDIA_TYPE)); + //} } HRESULT DSOutputFilter::setMediaType(const AM_MEDIA_TYPE* pmt) { - return this->ReconnectPin(this->outputStream, pmt); + return this->ReconnectPin(this->outputStream, pmt); } HRESULT DSOutputFilter::setImageFormat(UINT width, UINT height) { - return this->outputStream->setImageFormat(width, height); + return this->outputStream->setImageFormat(width, height); } bool DSOutputFilter::getImageFormat(UINT &width, UINT &height) { - if(this->outputStream){ - return this->outputStream->getImageFormat(width, height); - } - return false; + if(this->outputStream) { + return this->outputStream->getImageFormat(width, height); + } + return false; } void DSOutputFilter::setFps(int fps_) { - this->outputStream->setFps(fps_); + this->outputStream->setFps(fps_); } void DSOutputFilter::showOverlay(int value) { - this->outputStream->showOverlay(value); + this->outputStream->showOverlay(value); } void DSOutputFilter::reset() { - this->outputStream->frameNumber = 0; - this->outputStream->lockBuffer(); - this->outputStream->buffer = NULL; - this->outputStream->buffer_size = 0; - this->outputStream->unlockBuffer(); + this->outputStream->frameNumber = 0; + this->outputStream->lockBuffer(); + this->outputStream->buffer = NULL; + this->outputStream->buffer_size = 0; + this->outputStream->unlockBuffer(); } #ifdef _WIN32_WCE STDMETHODIMP_(ULONG) DSOutputFilter::NonDelegatingRelease() { - if(InterlockedDecrement(&m_cRef) == 0) - { - delete this; - return 0; - } - return m_cRef; + if(InterlockedDecrement(&m_cRef) == 0) { + delete this; + return 0; + } + return m_cRef; } #endif diff --git a/plugins/pluginDirectShow/internals/DSOutputFilter.h b/plugins/pluginDirectShow/internals/DSOutputFilter.h index fea2d23..eb424c4 100755 --- a/plugins/pluginDirectShow/internals/DSOutputFilter.h +++ b/plugins/pluginDirectShow/internals/DSOutputFilter.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,87 +26,87 @@ class DSOutputStream; // {17D9D5CB-850D-4339-B72A-F72D084D8D64} -TDSHOW_DEFINE_GUID(CLSID_TdshowOutputFilter, -0x17d9d5cb, 0x850d, 0x4339, 0xb7, 0x2a, 0xf7, 0x2d, 0x8, 0x4d, 0x8d, 0x64); +TDSHOW_DEFINE_GUID(CLSID_TdshowOutputFilter, + 0x17d9d5cb, 0x850d, 0x4339, 0xb7, 0x2a, 0xf7, 0x2d, 0x8, 0x4d, 0x8d, 0x64); class DSOutputFilter : public CSource, public DSBufferWriter { public: - DSOutputFilter(LPUNKNOWN pUnk, HRESULT *phr); - virtual ~DSOutputFilter(); - - //static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - DECLARE_IUNKNOWN; - - virtual void setBuffer(void *pointer, int size); - virtual inline HRESULT setImageFormat(UINT width, UINT height); - virtual bool getImageFormat(UINT &width, UINT &height); + DSOutputFilter(LPUNKNOWN pUnk, HRESULT *phr); + virtual ~DSOutputFilter(); + + //static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); + DECLARE_IUNKNOWN; + + virtual void setBuffer(void *pointer, int size); + virtual inline HRESULT setImageFormat(UINT width, UINT height); + virtual bool getImageFormat(UINT &width, UINT &height); - virtual void setFps(int fps_); - virtual void showOverlay(int value); + virtual void setFps(int fps_); + virtual void showOverlay(int value); - virtual void getMediaType(AM_MEDIA_TYPE* &pmt); - virtual HRESULT setMediaType(const AM_MEDIA_TYPE* pmt); + virtual void getMediaType(AM_MEDIA_TYPE* &pmt); + virtual HRESULT setMediaType(const AM_MEDIA_TYPE* pmt); - void reset(); + void reset(); #ifdef _WIN32_WCE - STDMETHODIMP_(ULONG) NonDelegatingRelease(); + STDMETHODIMP_(ULONG) NonDelegatingRelease(); #endif //protected: #ifdef _WIN32_WCE - /*STDMETHODIMP QueryInterface(REFIID riid, void **ppv) - { - CheckPointer(ppv, E_POINTER); - - if (riid == IID_IBaseFilter - || riid == IID_IBaseFilter - || riid == IID_IUnknown - || riid == IID_IMediaFilter - ) - { - return GetInterface((IBaseFilter *) this, ppv); - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } + /*STDMETHODIMP QueryInterface(REFIID riid, void **ppv) + { + CheckPointer(ppv, E_POINTER); + + if (riid == IID_IBaseFilter + || riid == IID_IBaseFilter + || riid == IID_IUnknown + || riid == IID_IMediaFilter + ) + { + return GetInterface((IBaseFilter *) this, ppv); + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } }; STDMETHODIMP_(ULONG) AddRef() { - //return GetOwner()->AddRef(); - //return 1; - return (ULONG)InterlockedIncrement(&m_cRef); + //return GetOwner()->AddRef(); + //return 1; + return (ULONG)InterlockedIncrement(&m_cRef); }; STDMETHODIMP_(ULONG) Release() { LONG lRefCount = InterlockedDecrement(&m_cRef); - if(m_cRef < 1) delete this; - return (ULONG)m_cRef; + if(m_cRef < 1) delete this; + return (ULONG)m_cRef; }; - STDMETHODIMP_(ULONG) NonDelegatingAddRef() - { - return InterlockedIncrement(&m_cRef); - }*/ + STDMETHODIMP_(ULONG) NonDelegatingAddRef() + { + return InterlockedIncrement(&m_cRef); + }*/ #endif -/* - STDMETHODIMP_(ULONG) NonDelegatingRelease() - { - if(InterlockedDecrement(&m_cRef) == 0) - { - delete this; - return 0; - } - return m_cRef; - }*/ + /* + STDMETHODIMP_(ULONG) NonDelegatingRelease() + { + if(InterlockedDecrement(&m_cRef) == 0) + { + delete this; + return 0; + } + return m_cRef; + }*/ private: - DSOutputStream *outputStream; + DSOutputStream *outputStream; - friend class DSOutputStream; + friend class DSOutputStream; }; #endif diff --git a/plugins/pluginDirectShow/internals/DSOutputStream.cxx b/plugins/pluginDirectShow/internals/DSOutputStream.cxx index 670d0ae..1e13d78 100755 --- a/plugins/pluginDirectShow/internals/DSOutputStream.cxx +++ b/plugins/pluginDirectShow/internals/DSOutputStream.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -34,280 +34,281 @@ using namespace std; #define OVERLAY_TEXT TEXT("Press ESC to exit full screen mode") #define OVERLAY_DURATION 3 // in seconds -DSOutputStream::DSOutputStream(HRESULT *phr, DSOutputFilter *pParent, LPCWSTR pPinName) -: CSourceStream(_T("DSOutputStream"), phr, pParent, pPinName) +DSOutputStream::DSOutputStream(HRESULT *phr, DSOutputFilter *pParent, LPCWSTR pPinName) + : CSourceStream(_T("DSOutputStream"), phr, pParent, pPinName) { #if !(defined(_WIN32_WCE) && defined(_DEBUG)) - CAutoLock cAutoLock(m_pFilter->pStateLock()); + CAutoLock cAutoLock(m_pFilter->pStateLock()); #endif - this->buffer = NULL; - this->buffer_size = NULL; + this->buffer = NULL; + this->buffer_size = NULL; - this->frameNumber = 0; - this->frameLength = (1000)/DEFAULT_FPS; - this->fps = DEFAULT_FPS; + this->frameNumber = 0; + this->frameLength = (1000)/DEFAULT_FPS; + this->fps = DEFAULT_FPS; - this->width = 352; - this->height = 288; + this->width = 352; + this->height = 288; - this->overlay = false; + this->overlay = false; - this->paintBuffer = NULL; - this->paintDC = NULL; - this->hDibSection = NULL; - this->hObject = NULL; + this->paintBuffer = NULL; + this->paintDC = NULL; + this->hDibSection = NULL; + this->hObject = NULL; - this->mutex = tsk_mutex_create(); + this->mutex = tsk_mutex_create(); } DSOutputStream::~DSOutputStream() { - TSK_FREE(this->buffer); - tsk_mutex_destroy(&this->mutex); - // TODO : Is there anything to free ??? + TSK_FREE(this->buffer); + tsk_mutex_destroy(&this->mutex); + // TODO : Is there anything to free ??? } void DSOutputStream::setFps(int fps_) { - this->fps = fps_; - this->frameLength = (1000)/this->fps; + this->fps = fps_; + this->frameLength = (1000)/this->fps; } void DSOutputStream::showOverlay(int value) { - if (value == 0){ - this->overlay = false; - } - this->overlay = (value > 0); + if (value == 0) { + this->overlay = false; + } + this->overlay = (value > 0); } HRESULT DSOutputStream::setImageFormat(UINT width, UINT height) { - if ((this->width == width) && (this->height == height)) return S_FALSE; + if ((this->width == width) && (this->height == height)) { + return S_FALSE; + } - this->width = width; - this->height = height; + this->width = width; + this->height = height; - this->frameNumber = 0; + this->frameNumber = 0; - return S_OK; + return S_OK; } bool DSOutputStream::getImageFormat(UINT &width, UINT &height) { - width = this->width; - height = this->height; - return true; + width = this->width; + height = this->height; + return true; } HRESULT DSOutputStream::GetMediaType(CMediaType *pMediaType) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; #if !(defined(_WIN32_WCE) && defined(_DEBUG)) - CAutoLock lock(m_pFilter->pStateLock()); + CAutoLock lock(m_pFilter->pStateLock()); #endif - ZeroMemory(pMediaType, sizeof(CMediaType)); - - VIDEOINFO *pvi = (VIDEOINFO *)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFO)); - if (NULL == pvi) - return E_OUTOFMEMORY; - - ZeroMemory(pvi, sizeof(VIDEOINFO)); - - pvi->bmiHeader.biCompression = BI_RGB; - pvi->bmiHeader.biBitCount = 24; - pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pvi->bmiHeader.biWidth = this->width; - pvi->bmiHeader.biHeight = this->height; - pvi->bmiHeader.biPlanes = 1; - pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); - pvi->bmiHeader.biClrImportant = 0; - - // Frame rate - pvi->AvgTimePerFrame = DS_MILLIS_TO_100NS(1000/this->fps); - - SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. - SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle - - pMediaType->SetType(&MEDIATYPE_Video); - pMediaType->SetFormatType(&FORMAT_VideoInfo); - pMediaType->SetTemporalCompression(FALSE); - - pMediaType->SetSubtype(&MEDIASUBTYPE_RGB24); - pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage); - - bitmapInfo.bmiHeader = pvi->bmiHeader; - - return hr; + ZeroMemory(pMediaType, sizeof(CMediaType)); + + VIDEOINFO *pvi = (VIDEOINFO *)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFO)); + if (NULL == pvi) { + return E_OUTOFMEMORY; + } + + ZeroMemory(pvi, sizeof(VIDEOINFO)); + + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 24; + pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pvi->bmiHeader.biWidth = this->width; + pvi->bmiHeader.biHeight = this->height; + pvi->bmiHeader.biPlanes = 1; + pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); + pvi->bmiHeader.biClrImportant = 0; + + // Frame rate + pvi->AvgTimePerFrame = DS_MILLIS_TO_100NS(1000/this->fps); + + SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. + SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle + + pMediaType->SetType(&MEDIATYPE_Video); + pMediaType->SetFormatType(&FORMAT_VideoInfo); + pMediaType->SetTemporalCompression(FALSE); + + pMediaType->SetSubtype(&MEDIASUBTYPE_RGB24); + pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage); + + bitmapInfo.bmiHeader = pvi->bmiHeader; + + return hr; } HRESULT DSOutputStream::DecideBufferSize(IMemAllocator *pMemAlloc, ALLOCATOR_PROPERTIES *pProperties) { - CheckPointer(pMemAlloc, E_POINTER); - CheckPointer(pProperties, E_POINTER); + CheckPointer(pMemAlloc, E_POINTER); + CheckPointer(pProperties, E_POINTER); #if !(defined(_WIN32_WCE) && defined(_DEBUG)) - CAutoLock cAutoLock(m_pFilter->pStateLock()); + CAutoLock cAutoLock(m_pFilter->pStateLock()); #endif - HRESULT hr = NOERROR; - - VIDEOINFO *pvi = (VIDEOINFO *) m_mt.Format(); - pProperties->cBuffers = 1; - pProperties->cbBuffer = pvi->bmiHeader.biSizeImage; - - // Ask the allocator to reserve us some sample memory. NOTE: the function - // can succeed (return NOERROR) but still not have allocated the - // memory that we requested, so we must check we got whatever we wanted. - ALLOCATOR_PROPERTIES Actual; - hr = pMemAlloc->SetProperties(pProperties,&Actual); - if(FAILED(hr)){ - return hr; - } - - // Is this allocator unsuitable? - if(Actual.cbBuffer < pProperties->cbBuffer) - { - return E_FAIL; - } - - // Make sure that we have only 1 buffer (we erase the ball in the - // old buffer to save having to zero a 200k+ buffer every time - // we draw a frame) - return NOERROR; + HRESULT hr = NOERROR; + + VIDEOINFO *pvi = (VIDEOINFO *) m_mt.Format(); + pProperties->cBuffers = 1; + pProperties->cbBuffer = pvi->bmiHeader.biSizeImage; + + // Ask the allocator to reserve us some sample memory. NOTE: the function + // can succeed (return NOERROR) but still not have allocated the + // memory that we requested, so we must check we got whatever we wanted. + ALLOCATOR_PROPERTIES Actual; + hr = pMemAlloc->SetProperties(pProperties,&Actual); + if(FAILED(hr)) { + return hr; + } + + // Is this allocator unsuitable? + if(Actual.cbBuffer < pProperties->cbBuffer) { + return E_FAIL; + } + + // Make sure that we have only 1 buffer (we erase the ball in the + // old buffer to save having to zero a 200k+ buffer every time + // we draw a frame) + return NOERROR; } HRESULT DSOutputStream::OnThreadCreate() { #if OVERLAY - hDibSection = CreateDIBSection(NULL, (BITMAPINFO *) &bitmapInfo, DIB_RGB_COLORS, &paintBuffer, NULL, 0); + hDibSection = CreateDIBSection(NULL, (BITMAPINFO *) &bitmapInfo, DIB_RGB_COLORS, &paintBuffer, NULL, 0); - HDC hDC = GetDC(NULL); - paintDC = CreateCompatibleDC(hDC); - SetMapMode(paintDC, GetMapMode(hDC)); - SetBkMode(paintDC, TRANSPARENT); - SetTextColor(paintDC, RGB(255,255,255)); + HDC hDC = GetDC(NULL); + paintDC = CreateCompatibleDC(hDC); + SetMapMode(paintDC, GetMapMode(hDC)); + SetBkMode(paintDC, TRANSPARENT); + SetTextColor(paintDC, RGB(255,255,255)); - hObject = SelectObject(paintDC, hDibSection); + hObject = SelectObject(paintDC, hDibSection); #endif - return CSourceStream::OnThreadCreate(); + return CSourceStream::OnThreadCreate(); } HRESULT DSOutputStream::OnThreadDestroy() { #if OVERLAY - if (paintDC) DeleteDC(paintDC); - if (hObject) DeleteObject(hObject); - - if (paintBuffer) - { - //delete[] paintBuffer; // will be done - //paintBuffer = NULL; - } + if (paintDC) { + DeleteDC(paintDC); + } + if (hObject) { + DeleteObject(hObject); + } + + if (paintBuffer) { + //delete[] paintBuffer; // will be done + //paintBuffer = NULL; + } #endif - return CSourceStream::OnThreadDestroy(); + return CSourceStream::OnThreadDestroy(); } inline HRESULT DSOutputStream::DrawOverLay(void *pBuffer, long lSize) { - // called only #if OVERLAY - CopyMemory(paintBuffer, pBuffer, lSize); + // called only #if OVERLAY + CopyMemory(paintBuffer, pBuffer, lSize); - // Draw the current frame + // Draw the current frame #ifdef _WIN32_WCE - + #else - if( !TextOut( paintDC, 0, 0, OVERLAY_TEXT, (int)_tcslen( OVERLAY_TEXT ) ) ) return E_FAIL; + if( !TextOut( paintDC, 0, 0, OVERLAY_TEXT, (int)_tcslen( OVERLAY_TEXT ) ) ) { + return E_FAIL; + } #endif - - CopyMemory(pBuffer, paintBuffer, lSize); - return S_OK; + CopyMemory(pBuffer, paintBuffer, lSize); + + return S_OK; } static __inline void TransfertBuffer(void* src, void* dest, long lSize) { - __try - { + __try { #if MEMCPY_WORKAROUND - //#ifdef _WIN32_WCE - memmove(dest, src, lSize); - /*#else - unsigned char * pDst = (unsigned char *) dest; - - if(src){ - unsigned char const * pSrc = (unsigned char const *) src; - for( register int i=0; ((i< lSize) && src); i++) *pDst++ = *pSrc++; - }else{ - for( register int i=0; i< lSize; i++) *pDst++ = 0; - } - #endif*/ + //#ifdef _WIN32_WCE + memmove(dest, src, lSize); + /*#else + unsigned char * pDst = (unsigned char *) dest; + + if(src){ + unsigned char const * pSrc = (unsigned char const *) src; + for( register int i=0; ((i< lSize) && src); i++) *pDst++ = *pSrc++; + }else{ + for( register int i=0; i< lSize; i++) *pDst++ = 0; + } + #endif*/ #else - CopyMemory(dest, src, lSize); //BUGGY + CopyMemory(dest, src, lSize); //BUGGY #endif - } - __except(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()) - { - //ZeroMemory(dest, sizeof(void*)); - } + } + __except(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()) { + //ZeroMemory(dest, sizeof(void*)); + } } HRESULT DSOutputStream::FillBuffer(IMediaSample *pSample) { - CheckPointer(pSample, E_POINTER); + CheckPointer(pSample, E_POINTER); #if !(defined(_WIN32_WCE) && defined(_DEBUG)) - CAutoLock lock(m_pFilter->pStateLock()); + CAutoLock lock(m_pFilter->pStateLock()); #endif - HRESULT hr; - BYTE *pBuffer = NULL; - long lSize, lDataSize; + HRESULT hr; + BYTE *pBuffer = NULL; + long lSize, lDataSize; - hr = pSample->GetPointer(&pBuffer); - if (SUCCEEDED(hr)) - { - lDataSize = lSize = pSample->GetSize(); + hr = pSample->GetPointer(&pBuffer); + if (SUCCEEDED(hr)) { + lDataSize = lSize = pSample->GetSize(); - // Check that we're still using video - //ASSERT(m_mt.formattype == FORMAT_VideoInfo); + // Check that we're still using video + //ASSERT(m_mt.formattype == FORMAT_VideoInfo); - if (this->buffer) - { + if (this->buffer) { #if OVERLAY - if (this->overlay) - { - DrawOverLay(this->buffer, lSize); - } + if (this->overlay) { + DrawOverLay(this->buffer, lSize); + } #endif - // Why try do not work, see: http://msdn2.microsoft.com/en-us/library/xwtb73ad(vs.80).aspx - this->lockBuffer(); - lDataSize = TSK_MIN(lSize, this->buffer_size); - TransfertBuffer(this->buffer, (void*)pBuffer, lDataSize); - this->unlockBuffer(); - } - else - { - // Avoid caching last image - memset((void*)pBuffer, NULL, lSize); - } - - REFERENCE_TIME rtStart = DS_MILLIS_TO_100NS(this->frameNumber * this->frameLength); - REFERENCE_TIME rtStop = rtStart + DS_MILLIS_TO_100NS(this->frameLength); - - this->frameNumber++; - - pSample->SetTime(&rtStart, &rtStop); - //pSample->SetMediaTime(&rtStart, &rtStop); - pSample->SetActualDataLength(lDataSize); - pSample->SetPreroll(FALSE); - pSample->SetDiscontinuity(FALSE); - } - - // Set TRUE on every sample for uncompressed frames (KEYFRAME) - pSample->SetSyncPoint(TRUE); - - return S_OK; + // Why try do not work, see: http://msdn2.microsoft.com/en-us/library/xwtb73ad(vs.80).aspx + this->lockBuffer(); + lDataSize = TSK_MIN(lSize, this->buffer_size); + TransfertBuffer(this->buffer, (void*)pBuffer, lDataSize); + this->unlockBuffer(); + } + else { + // Avoid caching last image + memset((void*)pBuffer, NULL, lSize); + } + + REFERENCE_TIME rtStart = DS_MILLIS_TO_100NS(this->frameNumber * this->frameLength); + REFERENCE_TIME rtStop = rtStart + DS_MILLIS_TO_100NS(this->frameLength); + + this->frameNumber++; + + pSample->SetTime(&rtStart, &rtStop); + //pSample->SetMediaTime(&rtStart, &rtStop); + pSample->SetActualDataLength(lDataSize); + pSample->SetPreroll(FALSE); + pSample->SetDiscontinuity(FALSE); + } + + // Set TRUE on every sample for uncompressed frames (KEYFRAME) + pSample->SetSyncPoint(TRUE); + + return S_OK; } diff --git a/plugins/pluginDirectShow/internals/DSOutputStream.h b/plugins/pluginDirectShow/internals/DSOutputStream.h index db3ede4..211bdd8 100755 --- a/plugins/pluginDirectShow/internals/DSOutputStream.h +++ b/plugins/pluginDirectShow/internals/DSOutputStream.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -29,61 +29,63 @@ class DSOutputFilter; class DSOutputStream : public CSourceStream { public: - DSOutputStream(HRESULT *phr, DSOutputFilter *pParent, LPCWSTR pPinName); - virtual ~DSOutputStream(); - - void setFps(int fps_); - void showOverlay(int value); - - HRESULT setImageFormat(UINT width, UINT height); - bool getImageFormat(UINT &width, UINT &height); - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_NOTIMPL; }; - inline bool lockBuffer() { - if (this->mutex) { - return tsk_mutex_lock(this->mutex) == 0; - } - return false; - } - inline bool unlockBuffer() { - if (this->mutex) { - return tsk_mutex_unlock(this->mutex) == 0; - } - return false; - } + DSOutputStream(HRESULT *phr, DSOutputFilter *pParent, LPCWSTR pPinName); + virtual ~DSOutputStream(); + + void setFps(int fps_); + void showOverlay(int value); + + HRESULT setImageFormat(UINT width, UINT height); + bool getImageFormat(UINT &width, UINT &height); + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { + return E_NOTIMPL; + }; + inline bool lockBuffer() { + if (this->mutex) { + return tsk_mutex_lock(this->mutex) == 0; + } + return false; + } + inline bool unlockBuffer() { + if (this->mutex) { + return tsk_mutex_unlock(this->mutex) == 0; + } + return false; + } public: - void *buffer; - int buffer_size; - LONGLONG frameNumber; + void *buffer; + int buffer_size; + LONGLONG frameNumber; protected: // Overrides - HRESULT GetMediaType(CMediaType *pMediaType); - HRESULT DecideBufferSize(IMemAllocator *pMemAlloc, ALLOCATOR_PROPERTIES *pProperties); - HRESULT OnThreadCreate(); - HRESULT OnThreadDestroy(); - HRESULT FillBuffer(IMediaSample *pSample); + HRESULT GetMediaType(CMediaType *pMediaType); + HRESULT DecideBufferSize(IMemAllocator *pMemAlloc, ALLOCATOR_PROPERTIES *pProperties); + HRESULT OnThreadCreate(); + HRESULT OnThreadDestroy(); + HRESULT FillBuffer(IMediaSample *pSample); private: - inline HRESULT DrawOverLay(void *pBuffer, long lSize); + inline HRESULT DrawOverLay(void *pBuffer, long lSize); private: - // TIMING - REFERENCE_TIME frameLength; - int fps; - - // sizing - UINT width; - UINT height; - - // overlaying - bool overlay; - BITMAPINFO bitmapInfo; - void *paintBuffer; - HDC paintDC; - HBITMAP hDibSection; - HGDIOBJ hObject; - - tsk_mutex_handle_t* mutex; + // TIMING + REFERENCE_TIME frameLength; + int fps; + + // sizing + UINT width; + UINT height; + + // overlaying + bool overlay; + BITMAPINFO bitmapInfo; + void *paintBuffer; + HDC paintDC; + HBITMAP hDibSection; + HGDIOBJ hObject; + + tsk_mutex_handle_t* mutex; }; diff --git a/plugins/pluginDirectShow/internals/DSPushSource.h b/plugins/pluginDirectShow/internals/DSPushSource.h index 140d9bd..e78c47e 100755 --- a/plugins/pluginDirectShow/internals/DSPushSource.h +++ b/plugins/pluginDirectShow/internals/DSPushSource.h @@ -12,7 +12,7 @@ #include <strsafe.h> -// UNITS = 10 ^ 7 +// UNITS = 10 ^ 7 // UNITS / 30 = 30 fps; // UNITS / 20 = 20 fps, etc const REFERENCE_TIME FPS_30 = UNITS / 30; @@ -35,8 +35,8 @@ const REFERENCE_TIME rtDefaultFrameLength = FPS_10; #define NUM_FILES 5 // {3FD3081A-A8C9-4958-9F75-07EC89690024} -TDSHOW_DEFINE_GUID(CLSID_PushSourceDesktop, -0x3fd3081a, 0xa8c9, 0x4958, 0x9f, 0x75, 0x7, 0xec, 0x89, 0x69, 0x0, 0x24); +TDSHOW_DEFINE_GUID(CLSID_PushSourceDesktop, + 0x3fd3081a, 0xa8c9, 0x4958, 0x9f, 0x75, 0x7, 0xec, 0x89, 0x69, 0x0, 0x24); @@ -56,11 +56,11 @@ protected: BITMAPINFO *m_pBmi; // Pointer to the bitmap header DWORD m_cbBitmapInfo; // Size of the bitmap header - - // File opening variables - HANDLE m_hFile; // Handle returned from CreateFile + + // File opening variables + HANDLE m_hFile; // Handle returned from CreateFile BYTE * m_pFile; // Points to beginning of file buffer - BYTE * m_pImage; // Points to pixel bits + BYTE * m_pImage; // Points to pixel bits int m_iFrameNumber; const REFERENCE_TIME m_rtFrameLength; @@ -77,13 +77,12 @@ public: HRESULT GetMediaType(CMediaType *pMediaType); HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } @@ -100,11 +99,11 @@ protected: BITMAPINFO *m_pBmi[NUM_FILES]; // Pointer to the bitmap headers DWORD m_cbBitmapInfo[NUM_FILES]; // Size of the bitmap headers - - // File opening variables - HANDLE m_hFile[NUM_FILES]; // Handles returned from CreateFile + + // File opening variables + HANDLE m_hFile[NUM_FILES]; // Handles returned from CreateFile BYTE * m_pFile[NUM_FILES]; // Points to beginning of file buffers - BYTE * m_pImage[NUM_FILES]; // Points to pixel bits + BYTE * m_pImage[NUM_FILES]; // Points to pixel bits BOOL m_bFilesLoaded; int m_iCurrentBitmap; // Which bitmap is being displayed @@ -123,13 +122,12 @@ public: HRESULT GetMediaType(CMediaType *pMediaType); HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } @@ -158,7 +156,7 @@ protected: CCritSec m_cSharedState; // Protects our internal state CImageDisplay m_Display; // Figures out our media type for us - HWND m_hSrcHwnd; // Handle to the window to grab + HWND m_hSrcHwnd; // Handle to the window to grab public: @@ -168,7 +166,7 @@ public: // Override the version that offers exactly one media type HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Set the agreed media type and set up the necessary parameters HRESULT SetMediaType(const CMediaType *pMediaType); @@ -177,19 +175,17 @@ public: HRESULT GetMediaType(int iPosition, CMediaType *pmt); // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } - HRESULT SetSrcHwnd(HWND hWnd) - { - m_hSrcHwnd = hWnd; - return S_OK; - } + HRESULT SetSrcHwnd(HWND hWnd) { + m_hSrcHwnd = hWnd; + return S_OK; + } }; @@ -206,7 +202,7 @@ private: CPushPinBitmap *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); }; @@ -222,7 +218,7 @@ private: CPushPinBitmapSet *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); }; @@ -238,10 +234,10 @@ private: CPushPinDesktop *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); - DECLARE_IUNKNOWN; - - HRESULT SetSrcHwnd(HWND hWnd); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + DECLARE_IUNKNOWN; + + HRESULT SetSrcHwnd(HWND hWnd); }; @@ -260,7 +256,7 @@ public: #include <strsafe.h> -// UNITS = 10 ^ 7 +// UNITS = 10 ^ 7 // UNITS / 30 = 30 fps; // UNITS / 20 = 20 fps, etc const REFERENCE_TIME FPS_30 = UNITS / 30; @@ -283,8 +279,8 @@ const REFERENCE_TIME rtDefaultFrameLength = FPS_10; #define NUM_FILES 5 // {3FD3081A-A8C9-4958-9F75-07EC89690024} -TDSHOW_DEFINE_GUID(CLSID_PushSourceDesktop, -0x3fd3081a, 0xa8c9, 0x4958, 0x9f, 0x75, 0x7, 0xec, 0x89, 0x69, 0x0, 0x24); +TDSHOW_DEFINE_GUID(CLSID_PushSourceDesktop, + 0x3fd3081a, 0xa8c9, 0x4958, 0x9f, 0x75, 0x7, 0xec, 0x89, 0x69, 0x0, 0x24); @@ -304,11 +300,11 @@ protected: BITMAPINFO *m_pBmi; // Pointer to the bitmap header DWORD m_cbBitmapInfo; // Size of the bitmap header - - // File opening variables - HANDLE m_hFile; // Handle returned from CreateFile + + // File opening variables + HANDLE m_hFile; // Handle returned from CreateFile BYTE * m_pFile; // Points to beginning of file buffer - BYTE * m_pImage; // Points to pixel bits + BYTE * m_pImage; // Points to pixel bits int m_iFrameNumber; const REFERENCE_TIME m_rtFrameLength; @@ -325,13 +321,12 @@ public: HRESULT GetMediaType(CMediaType *pMediaType); HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } @@ -348,11 +343,11 @@ protected: BITMAPINFO *m_pBmi[NUM_FILES]; // Pointer to the bitmap headers DWORD m_cbBitmapInfo[NUM_FILES]; // Size of the bitmap headers - - // File opening variables - HANDLE m_hFile[NUM_FILES]; // Handles returned from CreateFile + + // File opening variables + HANDLE m_hFile[NUM_FILES]; // Handles returned from CreateFile BYTE * m_pFile[NUM_FILES]; // Points to beginning of file buffers - BYTE * m_pImage[NUM_FILES]; // Points to pixel bits + BYTE * m_pImage[NUM_FILES]; // Points to pixel bits BOOL m_bFilesLoaded; int m_iCurrentBitmap; // Which bitmap is being displayed @@ -371,13 +366,12 @@ public: HRESULT GetMediaType(CMediaType *pMediaType); HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } @@ -406,7 +400,7 @@ protected: CCritSec m_cSharedState; // Protects our internal state CImageDisplay m_Display; // Figures out our media type for us - HWND m_hSrcHwnd; // Handle to the window to grab + HWND m_hSrcHwnd; // Handle to the window to grab public: @@ -416,7 +410,7 @@ public: // Override the version that offers exactly one media type HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest); HRESULT FillBuffer(IMediaSample *pSample); - + // Set the agreed media type and set up the necessary parameters HRESULT SetMediaType(const CMediaType *pMediaType); @@ -425,19 +419,17 @@ public: HRESULT GetMediaType(int iPosition, CMediaType *pmt); // Quality control - // Not implemented because we aren't going in real time. - // If the file-writing filter slows the graph down, we just do nothing, which means - // wait until we're unblocked. No frames are ever dropped. - STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) - { + // Not implemented because we aren't going in real time. + // If the file-writing filter slows the graph down, we just do nothing, which means + // wait until we're unblocked. No frames are ever dropped. + STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q) { return E_FAIL; } - HRESULT SetSrcHwnd(HWND hWnd) - { - m_hSrcHwnd = hWnd; - return S_OK; - } + HRESULT SetSrcHwnd(HWND hWnd) { + m_hSrcHwnd = hWnd; + return S_OK; + } }; @@ -454,7 +446,7 @@ private: CPushPinBitmap *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); }; @@ -470,7 +462,7 @@ private: CPushPinBitmapSet *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); }; @@ -486,10 +478,10 @@ private: CPushPinDesktop *m_pPin; public: - static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); - DECLARE_IUNKNOWN; - - HRESULT SetSrcHwnd(HWND hWnd); + static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); + DECLARE_IUNKNOWN; + + HRESULT SetSrcHwnd(HWND hWnd); }; diff --git a/plugins/pluginDirectShow/internals/DSPushSourceDesktop.cxx b/plugins/pluginDirectShow/internals/DSPushSourceDesktop.cxx index 1bdee9e..3e68ee2 100755 --- a/plugins/pluginDirectShow/internals/DSPushSourceDesktop.cxx +++ b/plugins/pluginDirectShow/internals/DSPushSourceDesktop.cxx @@ -18,27 +18,27 @@ /********************************************** * * CPushPinDesktop Class - * + * * **********************************************/ CPushPinDesktop::CPushPinDesktop(HRESULT *phr, CSource *pFilter) - : CSourceStream(NAME("Push Source Desktop"), phr, pFilter, L"Out"), - m_FramesWritten(0), - m_bZeroMemory(0), - m_iFrameNumber(0), - m_rtFrameLength(FPS_5), // Capture and display desktop 5 times per second - m_nCurrentBitDepth(24), - m_hSrcHwnd(NULL) + : CSourceStream(NAME("Push Source Desktop"), phr, pFilter, L"Out"), + m_FramesWritten(0), + m_bZeroMemory(0), + m_iFrameNumber(0), + m_rtFrameLength(FPS_5), // Capture and display desktop 5 times per second + m_nCurrentBitDepth(24), + m_hSrcHwnd(NULL) { - // The main point of this sample is to demonstrate how to take a DIB - // in host memory and insert it into a video stream. + // The main point of this sample is to demonstrate how to take a DIB + // in host memory and insert it into a video stream. - // To keep this sample as simple as possible, we just read the desktop image - // from a file and copy it into every frame that we send downstream. + // To keep this sample as simple as possible, we just read the desktop image + // from a file and copy it into every frame that we send downstream. // - // In the filter graph, we connect this filter to the AVI Mux, which creates - // the AVI file with the video frames we pass to it. In this case, + // In the filter graph, we connect this filter to the AVI Mux, which creates + // the AVI file with the video frames we pass to it. In this case, // the end result is a screen capture video (GDI images only, with no // support for overlay surfaces). @@ -60,7 +60,7 @@ CPushPinDesktop::CPushPinDesktop(HRESULT *phr, CSource *pFilter) } CPushPinDesktop::~CPushPinDesktop() -{ +{ DbgLog((LOG_TRACE, 3, TEXT("Frames written %d"), m_iFrameNumber)); } @@ -84,74 +84,76 @@ HRESULT CPushPinDesktop::GetMediaType(int iPosition, CMediaType *pmt) CheckPointer(pmt,E_POINTER); CAutoLock cAutoLock(m_pFilter->pStateLock()); - if(iPosition < 0) + if(iPosition < 0) { return E_INVALIDARG; + } // Have we run off the end of types? - if(iPosition > 4) + if(iPosition > 4) { return VFW_S_NO_MORE_ITEMS; + } VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO)); - if(NULL == pvi) + if(NULL == pvi) { return(E_OUTOFMEMORY); + } // Initialize the VideoInfo structure before configuring its members ZeroMemory(pvi, sizeof(VIDEOINFO)); - switch(iPosition) - { - case 0: - { - // Return our highest quality 32bit format - - // Since we use RGB888 (the default for 32 bit), there is - // no reason to use BI_BITFIELDS to specify the RGB - // masks. Also, not everything supports BI_BITFIELDS - pvi->bmiHeader.biCompression = BI_RGB; - pvi->bmiHeader.biBitCount = 32; - break; - } + switch(iPosition) { + case 0: { + // Return our highest quality 32bit format - case 1: - { // Return our 24bit format - pvi->bmiHeader.biCompression = BI_RGB; - pvi->bmiHeader.biBitCount = 24; - break; - } + // Since we use RGB888 (the default for 32 bit), there is + // no reason to use BI_BITFIELDS to specify the RGB + // masks. Also, not everything supports BI_BITFIELDS + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 32; + break; + } - case 2: - { - // 16 bit per pixel RGB565 + case 1: { + // Return our 24bit format + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 24; + break; + } - // Place the RGB masks as the first 3 doublewords in the palette area - for(int i = 0; i < 3; i++) - pvi->TrueColorInfo.dwBitMasks[i] = bits565[i]; + case 2: { + // 16 bit per pixel RGB565 - pvi->bmiHeader.biCompression = BI_BITFIELDS; - pvi->bmiHeader.biBitCount = 16; - break; + // Place the RGB masks as the first 3 doublewords in the palette area + for(int i = 0; i < 3; i++) { + pvi->TrueColorInfo.dwBitMasks[i] = bits565[i]; } - case 3: - { // 16 bits per pixel RGB555 + pvi->bmiHeader.biCompression = BI_BITFIELDS; + pvi->bmiHeader.biBitCount = 16; + break; + } - // Place the RGB masks as the first 3 doublewords in the palette area - for(int i = 0; i < 3; i++) - pvi->TrueColorInfo.dwBitMasks[i] = bits555[i]; + case 3: { + // 16 bits per pixel RGB555 - pvi->bmiHeader.biCompression = BI_BITFIELDS; - pvi->bmiHeader.biBitCount = 16; - break; + // Place the RGB masks as the first 3 doublewords in the palette area + for(int i = 0; i < 3; i++) { + pvi->TrueColorInfo.dwBitMasks[i] = bits555[i]; } - case 4: - { // 8 bit palettised + pvi->bmiHeader.biCompression = BI_BITFIELDS; + pvi->bmiHeader.biBitCount = 16; + break; + } - pvi->bmiHeader.biCompression = BI_RGB; - pvi->bmiHeader.biBitCount = 8; - pvi->bmiHeader.biClrUsed = iPALETTE_COLORS; - break; - } + case 4: { + // 8 bit palettised + + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 8; + pvi->bmiHeader.biClrUsed = iPALETTE_COLORS; + break; + } } // Adjust the parameters common to all formats @@ -191,38 +193,37 @@ HRESULT CPushPinDesktop::CheckMediaType(const CMediaType *pMediaType) CheckPointer(pMediaType,E_POINTER); if((*(pMediaType->Type()) != MEDIATYPE_Video) || // we only output video - !(pMediaType->IsFixedSize())) // in fixed size samples - { + !(pMediaType->IsFixedSize())) { // in fixed size samples return E_INVALIDARG; } // Check for the subtypes we support const GUID *SubType = pMediaType->Subtype(); - if (SubType == NULL) + if (SubType == NULL) { return E_INVALIDARG; + } if( (*SubType != MEDIASUBTYPE_RGB24) #if 0 - && (*SubType != MEDIASUBTYPE_RGB565) - && (*SubType != MEDIASUBTYPE_RGB555) - && (*SubType != MEDIASUBTYPE_RGB32) - && (*SubType != MEDIASUBTYPE_RGB8) + && (*SubType != MEDIASUBTYPE_RGB565) + && (*SubType != MEDIASUBTYPE_RGB555) + && (*SubType != MEDIASUBTYPE_RGB32) + && (*SubType != MEDIASUBTYPE_RGB8) #endif - ) - { + ) { return E_INVALIDARG; } // Get the format area of the media type VIDEOINFO *pvi = (VIDEOINFO *) pMediaType->Format(); - if(pvi == NULL) + if(pvi == NULL) { return E_INVALIDARG; + } // Check if the image width & height have changed - if( pvi->bmiHeader.biWidth != m_iImageWidth || - abs(pvi->bmiHeader.biHeight) != m_iImageHeight) - { + if( pvi->bmiHeader.biWidth != m_iImageWidth || + abs(pvi->bmiHeader.biHeight) != m_iImageHeight) { // If the image width/height is changed, fail CheckMediaType() to force // the renderer to resize the image. return E_INVALIDARG; @@ -230,8 +231,9 @@ HRESULT CPushPinDesktop::CheckMediaType(const CMediaType *pMediaType) // Don't accept formats with negative height, which would cause the desktop // image to be displayed upside down. - if (pvi->bmiHeader.biHeight < 0) + if (pvi->bmiHeader.biHeight < 0) { return E_INVALIDARG; + } return S_OK; // This format is acceptable. @@ -246,7 +248,7 @@ HRESULT CPushPinDesktop::CheckMediaType(const CMediaType *pMediaType) // Then we can ask for buffers of the correct size to contain them. // HRESULT CPushPinDesktop::DecideBufferSize(IMemAllocator *pAlloc, - ALLOCATOR_PROPERTIES *pProperties) + ALLOCATOR_PROPERTIES *pProperties) { CheckPointer(pAlloc,E_POINTER); CheckPointer(pProperties,E_POINTER); @@ -265,14 +267,12 @@ HRESULT CPushPinDesktop::DecideBufferSize(IMemAllocator *pAlloc, // memory that we requested, so we must check we got whatever we wanted. ALLOCATOR_PROPERTIES Actual; hr = pAlloc->SetProperties(pProperties,&Actual); - if(FAILED(hr)) - { + if(FAILED(hr)) { return hr; } // Is this allocator unsuitable? - if(Actual.cbBuffer < pProperties->cbBuffer) - { + if(Actual.cbBuffer < pProperties->cbBuffer) { return E_FAIL; } @@ -297,31 +297,30 @@ HRESULT CPushPinDesktop::SetMediaType(const CMediaType *pMediaType) // Pass the call up to my base class HRESULT hr = CSourceStream::SetMediaType(pMediaType); - if(SUCCEEDED(hr)) - { + if(SUCCEEDED(hr)) { VIDEOINFO * pvi = (VIDEOINFO *) m_mt.Format(); - if (pvi == NULL) + if (pvi == NULL) { return E_UNEXPECTED; + } - switch(pvi->bmiHeader.biBitCount) - { - case 8: // 8-bit palettized - case 16: // RGB565, RGB555 - case 24: // RGB24 - case 32: // RGB32 - // Save the current media type and bit depth - m_MediaType = *pMediaType; - m_nCurrentBitDepth = pvi->bmiHeader.biBitCount; - hr = S_OK; - break; - - default: - // We should never agree any other media types - ASSERT(FALSE); - hr = E_INVALIDARG; - break; + switch(pvi->bmiHeader.biBitCount) { + case 8: // 8-bit palettized + case 16: // RGB565, RGB555 + case 24: // RGB24 + case 32: // RGB32 + // Save the current media type and bit depth + m_MediaType = *pMediaType; + m_nCurrentBitDepth = pvi->bmiHeader.biBitCount; + hr = S_OK; + break; + + default: + // We should never agree any other media types + ASSERT(FALSE); + hr = E_INVALIDARG; + break; } - } + } return hr; @@ -332,7 +331,7 @@ HRESULT CPushPinDesktop::SetMediaType(const CMediaType *pMediaType) // FillBuffer is called once for every sample in the stream. HRESULT CPushPinDesktop::FillBuffer(IMediaSample *pSample) { - BYTE *pData; + BYTE *pData; long cbData; CheckPointer(pSample, E_POINTER); @@ -348,18 +347,19 @@ HRESULT CPushPinDesktop::FillBuffer(IMediaSample *pSample) VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)m_mt.pbFormat; - // Copy the DIB bits over into our filter's output buffer. + // Copy the DIB bits over into our filter's output buffer. // Since sample size may be larger than the image size, bound the copy size. int nSize = min(pVih->bmiHeader.biSizeImage, (DWORD) cbData); HDIB hDib = CopyScreenToBitmap(&m_rScreen, pData, (BITMAPINFO *) &(pVih->bmiHeader)); - if (hDib) + if (hDib) { DeleteObject(hDib); + } - // Set the timestamps that will govern playback frame rate. - // If this file is getting written out as an AVI, - // then you'll also need to configure the AVI Mux filter to - // set the Average Time Per Frame for the AVI Header. + // Set the timestamps that will govern playback frame rate. + // If this file is getting written out as an AVI, + // then you'll also need to configure the AVI Mux filter to + // set the Average Time Per Frame for the AVI Header. // The current time is the sample's start. REFERENCE_TIME rtStart = m_iFrameNumber * m_rtFrameLength; REFERENCE_TIME rtStop = rtStart + m_rtFrameLength; @@ -367,7 +367,7 @@ HRESULT CPushPinDesktop::FillBuffer(IMediaSample *pSample) pSample->SetTime(&rtStart, &rtStop); m_iFrameNumber++; - // Set TRUE on every sample for uncompressed frames + // Set TRUE on every sample for uncompressed frames pSample->SetSyncPoint(TRUE); return S_OK; @@ -382,28 +382,28 @@ HRESULT CPushPinDesktop::FillBuffer(IMediaSample *pSample) **********************************************/ CPushSourceDesktop::CPushSourceDesktop(IUnknown *pUnk, HRESULT *phr) - : CSource(NAME("PushSourceDesktop"), pUnk, CLSID_PushSourceDesktop) + : CSource(NAME("PushSourceDesktop"), pUnk, CLSID_PushSourceDesktop) { // The pin magically adds itself to our pin array. m_pPin = new CPushPinDesktop(phr, this); - if (phr) - { - if (m_pPin == NULL) - *phr = E_OUTOFMEMORY; - else - *phr = S_OK; - } + if (phr) { + if (m_pPin == NULL) { + *phr = E_OUTOFMEMORY; + } + else { + *phr = S_OK; + } + } } CPushSourceDesktop::~CPushSourceDesktop() { - if (m_pPin) - { - delete m_pPin; - m_pPin = NULL; - } + if (m_pPin) { + delete m_pPin; + m_pPin = NULL; + } } @@ -411,24 +411,24 @@ CUnknown * WINAPI CPushSourceDesktop::CreateInstance(IUnknown *pUnk, HRESULT *ph { CPushSourceDesktop *pNewFilter = new CPushSourceDesktop(pUnk, phr ); - if (phr) - { - if (pNewFilter == NULL) - *phr = E_OUTOFMEMORY; - else - *phr = S_OK; - } + if (phr) { + if (pNewFilter == NULL) { + *phr = E_OUTOFMEMORY; + } + else { + *phr = S_OK; + } + } return pNewFilter; } HRESULT CPushSourceDesktop::SetSrcHwnd(HWND hWnd) { - if (m_pPin) - { - return m_pPin->SetSrcHwnd(hWnd); - } - return E_FAIL; + if (m_pPin) { + return m_pPin->SetSrcHwnd(hWnd); + } + return E_FAIL; } #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/internals/DSScreenCastGraph.cxx b/plugins/pluginDirectShow/internals/DSScreenCastGraph.cxx index b425d65..efdb261 100755 --- a/plugins/pluginDirectShow/internals/DSScreenCastGraph.cxx +++ b/plugins/pluginDirectShow/internals/DSScreenCastGraph.cxx @@ -1,18 +1,18 @@ #if !defined(_WIN32_WCE) /* Copyright (C) 2014 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -29,46 +29,46 @@ using namespace std; DSScreenCastGraph::DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr) -: DSBaseCaptureGraph(callback, hr) + : DSBaseCaptureGraph(callback, hr) { - this->grabberCallback = callback; + this->grabberCallback = callback; - this->captureFormat = NULL; - this->captureGraphBuilder = NULL; - this->graphBuilder = NULL; + this->captureFormat = NULL; + this->captureGraphBuilder = NULL; + this->graphBuilder = NULL; - this->sourceFilter = NULL; - this->sampleGrabberFilter = NULL; + this->sourceFilter = NULL; + this->sampleGrabberFilter = NULL; - this->nullRendererFilter = NULL; - this->grabberController = NULL; - this->mediaController = NULL; - this->mediaEventController = NULL; + this->nullRendererFilter = NULL; + this->grabberController = NULL; + this->mediaController = NULL; + this->mediaEventController = NULL; - this->running = FALSE; - this->paused = FALSE; + this->running = FALSE; + this->paused = FALSE; - *hr = this->createCaptureGraph(); + *hr = this->createCaptureGraph(); } DSScreenCastGraph::~DSScreenCastGraph() { - SAFE_RELEASE(this->mediaEventController); - SAFE_RELEASE(this->mediaController); - SAFE_RELEASE(this->grabberController); + SAFE_RELEASE(this->mediaEventController); + SAFE_RELEASE(this->mediaController); + SAFE_RELEASE(this->grabberController); - SAFE_RELEASE(this->nullRendererFilter); - SAFE_RELEASE(this->sampleGrabberFilter); + SAFE_RELEASE(this->nullRendererFilter); + SAFE_RELEASE(this->sampleGrabberFilter); - SAFE_RELEASE(this->graphBuilder); - SAFE_RELEASE(this->captureGraphBuilder); + SAFE_RELEASE(this->graphBuilder); + SAFE_RELEASE(this->captureGraphBuilder); - SAFE_RELEASE(this->sourceFilter); + SAFE_RELEASE(this->sourceFilter); } HRESULT DSScreenCastGraph::setParameters(DSCaptureFormat *format, int framerate) { - return S_OK; + return S_OK; } #ifdef _WIN32_WCE @@ -77,181 +77,207 @@ HRESULT DSScreenCastGraph::setParameters(DSCaptureFormat *format, int framerate) HRESULT DSScreenCastGraph::connect() { - HRESULT hr; + HRESULT hr; - if (!this->sourceFilter){ - TSK_DEBUG_ERROR("Invalid source filter"); - return E_FAIL; - } + if (!this->sourceFilter) { + TSK_DEBUG_ERROR("Invalid source filter"); + return E_FAIL; + } #if 0 - if (!this->captureFormat){ - TSK_DEBUG_ERROR("Invalid capture format"); - return E_FAIL; - } + if (!this->captureFormat) { + TSK_DEBUG_ERROR("Invalid capture format"); + return E_FAIL; + } #endif - - hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); if(FAILED(hr)) { TSK_DEBUG_ERROR("ConnectFilters failed"); return hr; } - return hr; + hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + if(FAILED(hr)) { + TSK_DEBUG_ERROR("ConnectFilters failed"); + return hr; + } + + return hr; } HRESULT DSScreenCastGraph::disconnect() { - HRESULT hr; + HRESULT hr; - if (!this->sourceFilter) - { - return E_FAIL; - } + if (!this->sourceFilter) { + return E_FAIL; + } #if 0 - if (!this->captureFormat) - { - return E_FAIL; - } + if (!this->captureFormat) { + return E_FAIL; + } #endif - hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter); - hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); + hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter); + hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter); - return hr; + return hr; } HRESULT DSScreenCastGraph::start() { - HRESULT hr; - - if (isRunning() && !isPaused()) - { - return S_OK; - } - - hr = this->mediaController->Run(); - if (!SUCCEEDED(hr)) - { - TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Run() has failed with %ld", hr); - return hr; - } - this->running = true; - return hr; + HRESULT hr; + + if (isRunning() && !isPaused()) { + return S_OK; + } + + hr = this->mediaController->Run(); + if (!SUCCEEDED(hr)) { + TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Run() has failed with %ld", hr); + return hr; + } + this->running = true; + return hr; } HRESULT DSScreenCastGraph::pause() { - HRESULT hr = S_OK; - if (isRunning()) - { - hr = this->mediaController->Pause(); - if (SUCCEEDED(hr)) - { - this->paused = TRUE; - } - } - return hr; + HRESULT hr = S_OK; + if (isRunning()) { + hr = this->mediaController->Pause(); + if (SUCCEEDED(hr)) { + this->paused = TRUE; + } + } + return hr; } HRESULT DSScreenCastGraph::stop() { - if (!this->running) - { - return S_OK; - } - - HRESULT hr; - hr = this->mediaController->Stop(); - if (FAILED(hr)) - { - TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Stop() has failed with %ld", hr); - } - this->running = false; - this->paused = false; - return hr; + if (!this->running) { + return S_OK; + } + + HRESULT hr; + hr = this->mediaController->Stop(); + if (FAILED(hr)) { + TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Stop() has failed with %ld", hr); + } + this->running = false; + this->paused = false; + return hr; } bool DSScreenCastGraph::isRunning() { - return this->running; + return this->running; } bool DSScreenCastGraph::isPaused() { - return this->paused; + return this->paused; } HRESULT DSScreenCastGraph::getConnectedMediaType(AM_MEDIA_TYPE *mediaType) { - return this->grabberController->GetConnectedMediaType(mediaType); + return this->grabberController->GetConnectedMediaType(mediaType); } HRESULT DSScreenCastGraph::createCaptureGraph() { - HRESULT hr; - - // Create capture graph builder - hr = COCREATE(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2, this->captureGraphBuilder); - if(FAILED(hr)) return hr; - - // Create the graph builder - hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder); - if(FAILED(hr)) return hr; - - // Initialize the Capture Graph Builder. - hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder); - if(FAILED(hr)) return hr; - - // Create source filter - LPUNKNOWN pUnk = NULL; - this->sourceFilter = (CPushSourceDesktop*)CPushSourceDesktop::CreateInstance(pUnk, &hr); - if(FAILED(hr)) return hr; - this->sourceFilter->AddRef(); - - // Create the sample grabber filter - hr = COCREATE(CLSID_SampleGrabber, IID_IBaseFilter, this->sampleGrabberFilter); - if(FAILED(hr)) return hr; - - // Create the NULL renderer - hr = COCREATE(CLSID_NullRenderer, IID_IBaseFilter, this->nullRendererFilter); - if(FAILED(hr)) return hr; - - // Add source filter to the graph - hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_SCREENCAST); - if(FAILED(hr)) return hr; - - // Add sample grabber to the graph - hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER); - if(FAILED(hr)) return hr; - - // Add null renderer to the graph - hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER); - if(FAILED(hr)) return hr; - - // Find media control - hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController); - if(FAILED(hr)) return hr; - - // Create the sample grabber controller - hr = QUERY(this->sampleGrabberFilter, IID_ISampleGrabber, this->grabberController); - if(FAILED(hr)) return hr; - - // Set the sample grabber media type (RGB24) - // TODO : CHECK - AM_MEDIA_TYPE mt; - ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - mt.subtype = MEDIASUBTYPE_RGB24; - mt.formattype = FORMAT_VideoInfo; - - hr = this->grabberController->SetMediaType(&mt); - if(FAILED(hr)) return hr; - - // Set sample grabber media type - this->grabberController->SetOneShot(FALSE); - this->grabberController->SetBufferSamples(FALSE); - - hr = this->grabberController->SetCallback(this->grabberCallback, 1); - if(FAILED(hr)) return hr; - - return hr; + HRESULT hr; + + // Create capture graph builder + hr = COCREATE(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2, this->captureGraphBuilder); + if(FAILED(hr)) { + return hr; + } + + // Create the graph builder + hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder); + if(FAILED(hr)) { + return hr; + } + + // Initialize the Capture Graph Builder. + hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder); + if(FAILED(hr)) { + return hr; + } + + // Create source filter + LPUNKNOWN pUnk = NULL; + this->sourceFilter = (CPushSourceDesktop*)CPushSourceDesktop::CreateInstance(pUnk, &hr); + if(FAILED(hr)) { + return hr; + } + this->sourceFilter->AddRef(); + + // Create the sample grabber filter + hr = COCREATE(CLSID_SampleGrabber, IID_IBaseFilter, this->sampleGrabberFilter); + if(FAILED(hr)) { + return hr; + } + + // Create the NULL renderer + hr = COCREATE(CLSID_NullRenderer, IID_IBaseFilter, this->nullRendererFilter); + if(FAILED(hr)) { + return hr; + } + + // Add source filter to the graph + hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_SCREENCAST); + if(FAILED(hr)) { + return hr; + } + + // Add sample grabber to the graph + hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER); + if(FAILED(hr)) { + return hr; + } + + // Add null renderer to the graph + hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER); + if(FAILED(hr)) { + return hr; + } + + // Find media control + hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController); + if(FAILED(hr)) { + return hr; + } + + // Create the sample grabber controller + hr = QUERY(this->sampleGrabberFilter, IID_ISampleGrabber, this->grabberController); + if(FAILED(hr)) { + return hr; + } + + // Set the sample grabber media type (RGB24) + // TODO : CHECK + AM_MEDIA_TYPE mt; + ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Video; + mt.subtype = MEDIASUBTYPE_RGB24; + mt.formattype = FORMAT_VideoInfo; + + hr = this->grabberController->SetMediaType(&mt); + if(FAILED(hr)) { + return hr; + } + + // Set sample grabber media type + this->grabberController->SetOneShot(FALSE); + this->grabberController->SetBufferSamples(FALSE); + + hr = this->grabberController->SetCallback(this->grabberCallback, 1); + if(FAILED(hr)) { + return hr; + } + + return hr; } #endif /* _WIN32_WCE */
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/DSScreenCastGraph.h b/plugins/pluginDirectShow/internals/DSScreenCastGraph.h index d201668..38400d0 100755 --- a/plugins/pluginDirectShow/internals/DSScreenCastGraph.h +++ b/plugins/pluginDirectShow/internals/DSScreenCastGraph.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014 Mamadou DIOP. -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -31,67 +31,73 @@ class CPushSourceDesktop; class DSScreenCastGraph : public DSBaseCaptureGraph { public: - DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr); - virtual ~DSScreenCastGraph(); + DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr); + virtual ~DSScreenCastGraph(); - std::vector<DSCaptureFormat> *getFormats() { return &this->supportedFormats; }; + std::vector<DSCaptureFormat> *getFormats() { + return &this->supportedFormats; + }; - virtual HRESULT setSource(const std::string &devicePath) { return S_OK; } - HRESULT setParameters(DSCaptureFormat *format, int framerate); + virtual HRESULT setSource(const std::string &devicePath) { + return S_OK; + } + HRESULT setParameters(DSCaptureFormat *format, int framerate); - HRESULT connect(); - HRESULT disconnect(); + HRESULT connect(); + HRESULT disconnect(); - HRESULT start(); - HRESULT stop(); - HRESULT pause(); - bool isRunning(); - bool isPaused(); + HRESULT start(); + HRESULT stop(); + HRESULT pause(); + bool isRunning(); + bool isPaused(); - HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); + HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); - virtual std::string getDeviceId() const { return std::string("screencast"); } + virtual std::string getDeviceId() const { + return std::string("screencast"); + } private: - HRESULT createCaptureGraph(); + HRESULT createCaptureGraph(); private: - ISampleGrabberCB *grabberCallback; + ISampleGrabberCB *grabberCallback; - ICaptureGraphBuilder2 *captureGraphBuilder; - IGraphBuilder *graphBuilder; + ICaptureGraphBuilder2 *captureGraphBuilder; + IGraphBuilder *graphBuilder; - CPushSourceDesktop *sourceFilter; - IBaseFilter *nullRendererFilter; - IBaseFilter *sampleGrabberFilter; + CPushSourceDesktop *sourceFilter; + IBaseFilter *nullRendererFilter; + IBaseFilter *sampleGrabberFilter; - ISampleGrabber *grabberController; + ISampleGrabber *grabberController; - IMediaControl *mediaController; - IMediaEventEx *mediaEventController; + IMediaControl *mediaController; + IMediaEventEx *mediaEventController; - std::vector<DSCaptureFormat> supportedFormats; - DSCaptureFormat *captureFormat; + std::vector<DSCaptureFormat> supportedFormats; + DSCaptureFormat *captureFormat; - bool running; - bool paused; + bool running; + bool paused; }; #endif /* PLUGIN_DSHOW_DSSCREENCAST_H */ /* Copyright (C) 2014 Mamadou DIOP. -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -111,50 +117,56 @@ class CPushSourceDesktop; class DSScreenCastGraph : public DSBaseCaptureGraph { public: - DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr); - virtual ~DSScreenCastGraph(); + DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr); + virtual ~DSScreenCastGraph(); - std::vector<DSCaptureFormat> *getFormats() { return &this->supportedFormats; }; + std::vector<DSCaptureFormat> *getFormats() { + return &this->supportedFormats; + }; - virtual HRESULT setSource(const std::string &devicePath) { return S_OK; } - HRESULT setParameters(DSCaptureFormat *format, int framerate); + virtual HRESULT setSource(const std::string &devicePath) { + return S_OK; + } + HRESULT setParameters(DSCaptureFormat *format, int framerate); - HRESULT connect(); - HRESULT disconnect(); + HRESULT connect(); + HRESULT disconnect(); - HRESULT start(); - HRESULT stop(); - HRESULT pause(); - bool isRunning(); - bool isPaused(); + HRESULT start(); + HRESULT stop(); + HRESULT pause(); + bool isRunning(); + bool isPaused(); - HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); + HRESULT getConnectedMediaType(AM_MEDIA_TYPE *mediaType); - virtual std::string getDeviceId() const { return std::string("screencast"); } + virtual std::string getDeviceId() const { + return std::string("screencast"); + } private: - HRESULT createCaptureGraph(); + HRESULT createCaptureGraph(); private: - ISampleGrabberCB *grabberCallback; + ISampleGrabberCB *grabberCallback; - ICaptureGraphBuilder2 *captureGraphBuilder; - IGraphBuilder *graphBuilder; + ICaptureGraphBuilder2 *captureGraphBuilder; + IGraphBuilder *graphBuilder; - CPushSourceDesktop *sourceFilter; - IBaseFilter *nullRendererFilter; - IBaseFilter *sampleGrabberFilter; + CPushSourceDesktop *sourceFilter; + IBaseFilter *nullRendererFilter; + IBaseFilter *sampleGrabberFilter; - ISampleGrabber *grabberController; + ISampleGrabber *grabberController; - IMediaControl *mediaController; - IMediaEventEx *mediaEventController; + IMediaControl *mediaController; + IMediaEventEx *mediaEventController; - std::vector<DSCaptureFormat> supportedFormats; - DSCaptureFormat *captureFormat; + std::vector<DSCaptureFormat> supportedFormats; + DSCaptureFormat *captureFormat; - bool running; - bool paused; + bool running; + bool paused; }; #endif /* PLUGIN_DSHOW_DSSCREENCAST_H */ diff --git a/plugins/pluginDirectShow/internals/DSUtils.cxx b/plugins/pluginDirectShow/internals/DSUtils.cxx index 913c081..6187e0f 100755 --- a/plugins/pluginDirectShow/internals/DSUtils.cxx +++ b/plugins/pluginDirectShow/internals/DSUtils.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -29,221 +29,223 @@ HWND GetMainWindow() { - HWND hWnd; - if (!(hWnd = GetActiveWindow())) { - if (!(hWnd = GetForegroundWindow())) { + HWND hWnd; + if (!(hWnd = GetActiveWindow())) { + if (!(hWnd = GetForegroundWindow())) { #if !defined(_WIN32_WCE) - if (!(hWnd = GetConsoleWindow())) { - return NULL; - } + if (!(hWnd = GetConsoleWindow())) { + return NULL; + } #endif - } - } - return hWnd; + } + } + return hWnd; } bool IsMainThread() -{ - HWND hWnd = GetMainWindow(); - if (hWnd) { - DWORD mainTid = GetWindowThreadProcessId(hWnd, NULL); - DWORD currentTid = GetCurrentThreadId(); - return (mainTid == currentTid); - } - return false; +{ + HWND hWnd = GetMainWindow(); + if (hWnd) { + DWORD mainTid = GetWindowThreadProcessId(hWnd, NULL); + DWORD currentTid = GetCurrentThreadId(); + return (mainTid == currentTid); + } + return false; } bool IsD3D9Supported() { #if defined(_WIN32_WCE) - return false; + return false; #else - static bool g_bChecked = false; - static bool g_bSupported = false; - - if (g_bChecked) { - return g_bSupported; - } - g_bChecked = true; - HRESULT hr = S_OK; - IDirect3D9* pD3D = NULL; - D3DDISPLAYMODE mode = { 0 }; - D3DPRESENT_PARAMETERS pp = {0}; - IDirect3DDevice9* pDevice = NULL; - - if (!(pD3D = Direct3DCreate9(D3D_SDK_VERSION))) { + static bool g_bChecked = false; + static bool g_bSupported = false; + + if (g_bChecked) { + return g_bSupported; + } + g_bChecked = true; + HRESULT hr = S_OK; + IDirect3D9* pD3D = NULL; + D3DDISPLAYMODE mode = { 0 }; + D3DPRESENT_PARAMETERS pp = {0}; + IDirect3DDevice9* pDevice = NULL; + + if (!(pD3D = Direct3DCreate9(D3D_SDK_VERSION))) { hr = E_OUTOFMEMORY; - goto bail; + goto bail; } hr = pD3D->GetAdapterDisplayMode( - D3DADAPTER_DEFAULT, - &mode - ); - if (FAILED(hr)) { - goto bail; - } + D3DADAPTER_DEFAULT, + &mode + ); + if (FAILED(hr)) { + goto bail; + } hr = pD3D->CheckDeviceType( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - mode.Format, - D3DFMT_X8R8G8B8, - TRUE // windowed - ); - if (FAILED(hr)) { - goto bail; - } + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + mode.Format, + D3DFMT_X8R8G8B8, + TRUE // windowed + ); + if (FAILED(hr)) { + goto bail; + } pp.BackBufferFormat = D3DFMT_X8R8G8B8; pp.SwapEffect = D3DSWAPEFFECT_DISCARD; pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - pp.Windowed = TRUE; - pp.hDeviceWindow = GetDesktopWindow(); + pp.Windowed = TRUE; + pp.hDeviceWindow = GetDesktopWindow(); hr = pD3D->CreateDevice( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - pp.hDeviceWindow, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &pp, - &pDevice - ); - if (FAILED(hr)) { - goto bail; - } - - // Everythings is OK - g_bSupported = true; - TSK_DEBUG_INFO("D3D9 supported"); + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + pp.hDeviceWindow, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &pp, + &pDevice + ); + if (FAILED(hr)) { + goto bail; + } + + // Everythings is OK + g_bSupported = true; + TSK_DEBUG_INFO("D3D9 supported"); bail: - if (!g_bSupported) { - TSK_DEBUG_WARN("D3D9 not supported"); - } - SAFE_RELEASE(pDevice); - SAFE_RELEASE(pD3D); - return g_bSupported; + if (!g_bSupported) { + TSK_DEBUG_WARN("D3D9 not supported"); + } + SAFE_RELEASE(pDevice); + SAFE_RELEASE(pD3D); + return g_bSupported; #endif /* _WIN32_WCE */ } IPin *GetPin(IBaseFilter *filter, PIN_DIRECTION direction) { - IEnumPins *enumPins = NULL; - IPin *pin = NULL; - - HRESULT hr = filter->EnumPins(&enumPins); - if(!enumPins){ - return NULL; - } - - for(;;){ - ULONG fetched = 0; - PIN_DIRECTION pinDir = PIN_DIRECTION(-1); - pin = NULL; - - if (FAILED(enumPins->Next(1, &pin, &fetched))){ - enumPins->Release(); - return NULL; - } - - if (fetched == 1 && pin){ - pin->QueryDirection(&pinDir); - if(pinDir == direction){ - break; - } - pin->Release(); - } - } - - enumPins->Release(); - return pin; + IEnumPins *enumPins = NULL; + IPin *pin = NULL; + + HRESULT hr = filter->EnumPins(&enumPins); + if(!enumPins) { + return NULL; + } + + for(;;) { + ULONG fetched = 0; + PIN_DIRECTION pinDir = PIN_DIRECTION(-1); + pin = NULL; + + if (FAILED(enumPins->Next(1, &pin, &fetched))) { + enumPins->Release(); + return NULL; + } + + if (fetched == 1 && pin) { + pin->QueryDirection(&pinDir); + if(pinDir == direction) { + break; + } + pin->Release(); + } + } + + enumPins->Release(); + return pin; } HRESULT ConnectFilters(IGraphBuilder *graphBuilder, IBaseFilter *source, IBaseFilter *destination, AM_MEDIA_TYPE *mediaType) { - HRESULT hr; + HRESULT hr; - IPin *outPin = GetPin(source, PINDIR_OUTPUT); - IPin *inPin = GetPin(destination, PINDIR_INPUT); + IPin *outPin = GetPin(source, PINDIR_OUTPUT); + IPin *inPin = GetPin(destination, PINDIR_INPUT); - if (mediaType != NULL){ - hr = graphBuilder->ConnectDirect(outPin, inPin, mediaType); - } - else{ - hr = graphBuilder->Connect(outPin, inPin); - } + if (mediaType != NULL) { + hr = graphBuilder->ConnectDirect(outPin, inPin, mediaType); + } + else { + hr = graphBuilder->Connect(outPin, inPin); + } - SAFE_RELEASE(outPin); - SAFE_RELEASE(inPin); + SAFE_RELEASE(outPin); + SAFE_RELEASE(inPin); - return hr; + return hr; } HRESULT DisconnectFilters(IGraphBuilder *graphBuilder, IBaseFilter *source, IBaseFilter *destination) { - HRESULT hr; + HRESULT hr; - IPin *outPin = GetPin(source, PINDIR_OUTPUT); - IPin *inPin = GetPin(destination, PINDIR_INPUT); + IPin *outPin = GetPin(source, PINDIR_OUTPUT); + IPin *inPin = GetPin(destination, PINDIR_INPUT); - if (inPin){ - hr = graphBuilder->Disconnect(inPin); - } + if (inPin) { + hr = graphBuilder->Disconnect(inPin); + } - if (outPin){ - hr = graphBuilder->Disconnect(outPin); - } + if (outPin) { + hr = graphBuilder->Disconnect(outPin); + } - SAFE_RELEASE(outPin); - SAFE_RELEASE(inPin); + SAFE_RELEASE(outPin); + SAFE_RELEASE(inPin); - return hr; + return hr; } bool DisconnectAllFilters(IGraphBuilder *graphBuilder) { - IEnumFilters* filterEnum = NULL; - IBaseFilter* currentFilter = NULL; - ULONG fetched; - HRESULT hr; - - hr = graphBuilder->EnumFilters(&filterEnum); - if (FAILED(hr)) { - SAFE_RELEASE(filterEnum); - return false; - } - - while(filterEnum->Next(1, ¤tFilter, &fetched) == S_OK){ - hr = DisconnectFilters(graphBuilder, currentFilter, currentFilter); - SAFE_RELEASE(currentFilter); - } - SAFE_RELEASE(filterEnum); - SAFE_RELEASE(currentFilter); - return true; + IEnumFilters* filterEnum = NULL; + IBaseFilter* currentFilter = NULL; + ULONG fetched; + HRESULT hr; + + hr = graphBuilder->EnumFilters(&filterEnum); + if (FAILED(hr)) { + SAFE_RELEASE(filterEnum); + return false; + } + + while(filterEnum->Next(1, ¤tFilter, &fetched) == S_OK) { + hr = DisconnectFilters(graphBuilder, currentFilter, currentFilter); + SAFE_RELEASE(currentFilter); + } + SAFE_RELEASE(filterEnum); + SAFE_RELEASE(currentFilter); + return true; } bool RemoveAllFilters(IGraphBuilder *graphBuilder) { - IEnumFilters* filterEnum = NULL; - IBaseFilter* currentFilter = NULL; - ULONG fetched; - HRESULT hr; - - hr = graphBuilder->EnumFilters(&filterEnum); - if (FAILED(hr)) return false; - - while(filterEnum->Next(1, ¤tFilter, &fetched) == S_OK){ - hr = graphBuilder->RemoveFilter(currentFilter); - if (FAILED(hr)){ - SAFE_RELEASE(filterEnum); - return false; - } - SAFE_RELEASE(currentFilter); - filterEnum->Reset(); - } - - SAFE_RELEASE(filterEnum); - SAFE_RELEASE(currentFilter); - return true; + IEnumFilters* filterEnum = NULL; + IBaseFilter* currentFilter = NULL; + ULONG fetched; + HRESULT hr; + + hr = graphBuilder->EnumFilters(&filterEnum); + if (FAILED(hr)) { + return false; + } + + while(filterEnum->Next(1, ¤tFilter, &fetched) == S_OK) { + hr = graphBuilder->RemoveFilter(currentFilter); + if (FAILED(hr)) { + SAFE_RELEASE(filterEnum); + return false; + } + SAFE_RELEASE(currentFilter); + filterEnum->Reset(); + } + + SAFE_RELEASE(filterEnum); + SAFE_RELEASE(currentFilter); + return true; } @@ -257,109 +259,113 @@ bool RemoveAllFilters(IGraphBuilder *graphBuilder) // C Callback that dispatch event to create display on UI thread static LRESULT CALLBACK __create__WndProcWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - HANDLE* event = reinterpret_cast<HANDLE*>(wParam); - BOOL* isScreenCast = reinterpret_cast<BOOL*>(GetProp(hWnd, TEXT("screnCast"))); - - if(event && lParam){ - switch(uMsg){ - case WM_CREATE_DISPLAY_ON_UI_THREAD: - { - HRESULT hr; - DSDisplay** ppDisplay = reinterpret_cast<DSDisplay**>(lParam); - *ppDisplay = new DSDisplay(&hr); - SetEvent(event); - break; - } - case WM_CREATE_GRABBER_ON_UI_THREAD: - { - HRESULT hr; - DSGrabber** ppGrabber = reinterpret_cast<DSGrabber**>(lParam); - *ppGrabber = new DSGrabber(&hr, *isScreenCast); - SetEvent(event); - break; - } - } - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); + HANDLE* event = reinterpret_cast<HANDLE*>(wParam); + BOOL* isScreenCast = reinterpret_cast<BOOL*>(GetProp(hWnd, TEXT("screnCast"))); + + if(event && lParam) { + switch(uMsg) { + case WM_CREATE_DISPLAY_ON_UI_THREAD: { + HRESULT hr; + DSDisplay** ppDisplay = reinterpret_cast<DSDisplay**>(lParam); + *ppDisplay = new DSDisplay(&hr); + SetEvent(event); + break; + } + case WM_CREATE_GRABBER_ON_UI_THREAD: { + HRESULT hr; + DSGrabber** ppGrabber = reinterpret_cast<DSGrabber**>(lParam); + *ppGrabber = new DSGrabber(&hr, *isScreenCast); + SetEvent(event); + break; + } + } + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); } int createOnCurrentThead(HWND hWnd, void** ppRet, BOOL display, BOOL screnCast) { - HRESULT hr; - if(display) *ppRet = new DSDisplay(&hr); - else *ppRet = new DSGrabber(&hr, screnCast); - if(FAILED(hr)){ - TSK_DEBUG_ERROR("Failed to created DirectShow %s", display ? "Display" : "Grabber"); - SAFE_DELETE_PTR(*ppRet); - return -2; - } - return 0; + HRESULT hr; + if(display) { + *ppRet = new DSDisplay(&hr); + } + else { + *ppRet = new DSGrabber(&hr, screnCast); + } + if(FAILED(hr)) { + TSK_DEBUG_ERROR("Failed to created DirectShow %s", display ? "Display" : "Grabber"); + SAFE_DELETE_PTR(*ppRet); + return -2; + } + return 0; } int createOnUIThead(HWND hWnd, void** ppRet, BOOL display, BOOL screnCast) { - static BOOL __isScreenCastFalse = FALSE; - static BOOL __isScreenCastTrue = TRUE; - if(!ppRet){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (IsMainThread()) { - return createOnCurrentThead(hWnd, ppRet, display, screnCast); - } - else{ - TSK_DEBUG_INFO("Create DirectShow element on worker thread"); - HANDLE event = NULL; - int ret = 0; - DWORD retWait, retryCount = 3; - - if(!hWnd){ - if (!(hWnd = FindWindow(NULL, TEXT("Boghe - IMS/RCS Client")))) { - if(!(hWnd = GetMainWindow())){ - TSK_DEBUG_ERROR("No Window handle could be used"); - return -2; - } - } - } + static BOOL __isScreenCastFalse = FALSE; + static BOOL __isScreenCastTrue = TRUE; + if(!ppRet) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (IsMainThread()) { + return createOnCurrentThead(hWnd, ppRet, display, screnCast); + } + else { + TSK_DEBUG_INFO("Create DirectShow element on worker thread"); + HANDLE event = NULL; + int ret = 0; + DWORD retWait, retryCount = 3; + + if(!hWnd) { + if (!(hWnd = FindWindow(NULL, TEXT("Boghe - IMS/RCS Client")))) { + if(!(hWnd = GetMainWindow())) { + TSK_DEBUG_ERROR("No Window handle could be used"); + return -2; + } + } + } #if defined(_WIN32_WCE) - WNDPROC wndProc = (WNDPROC) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __create__WndProcWindow); + WNDPROC wndProc = (WNDPROC) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __create__WndProcWindow); #else - WNDPROC wndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) __create__WndProcWindow); + WNDPROC wndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) __create__WndProcWindow); #endif - if (!wndProc) { - TSK_DEBUG_ERROR("SetWindowLongPtr() failed with errcode=%d", GetLastError()); - return createOnCurrentThead(hWnd, ppRet, display, screnCast); - } - - if (!(event = CreateEvent(NULL, TRUE, FALSE, NULL))) { - TSK_DEBUG_ERROR("Failed to create new event"); - ret = -4; goto bail; - } - SetProp(hWnd, TEXT("screnCast"), screnCast ? &__isScreenCastTrue : &__isScreenCastFalse); - if (!PostMessage(hWnd, display ? WM_CREATE_DISPLAY_ON_UI_THREAD : WM_CREATE_GRABBER_ON_UI_THREAD, reinterpret_cast<WPARAM>(event), reinterpret_cast<LPARAM>(ppRet))) { - TSK_DEBUG_ERROR("PostMessageA() failed"); - ret = -5; goto bail; - } - - do { - retWait = WaitForSingleObject(event, WM_CREATE_ON_UI_THREAD_TIMEOUT); - } - while (retryCount-- > 0 && (retWait == WAIT_TIMEOUT)); - - bail: - // restore - if (hWnd && wndProc) { + if (!wndProc) { + TSK_DEBUG_ERROR("SetWindowLongPtr() failed with errcode=%d", GetLastError()); + return createOnCurrentThead(hWnd, ppRet, display, screnCast); + } + + if (!(event = CreateEvent(NULL, TRUE, FALSE, NULL))) { + TSK_DEBUG_ERROR("Failed to create new event"); + ret = -4; + goto bail; + } + SetProp(hWnd, TEXT("screnCast"), screnCast ? &__isScreenCastTrue : &__isScreenCastFalse); + if (!PostMessage(hWnd, display ? WM_CREATE_DISPLAY_ON_UI_THREAD : WM_CREATE_GRABBER_ON_UI_THREAD, reinterpret_cast<WPARAM>(event), reinterpret_cast<LPARAM>(ppRet))) { + TSK_DEBUG_ERROR("PostMessageA() failed"); + ret = -5; + goto bail; + } + + do { + retWait = WaitForSingleObject(event, WM_CREATE_ON_UI_THREAD_TIMEOUT); + } + while (retryCount-- > 0 && (retWait == WAIT_TIMEOUT)); + +bail: + // restore + if (hWnd && wndProc) { #if defined(_WIN32_WCE) - SetWindowLong(hWnd, GWL_WNDPROC, (LONG)wndProc); + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)wndProc); #else - SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)wndProc); + SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)wndProc); #endif - } - if (event) { - CloseHandle(event); - } + } + if (event) { + CloseHandle(event); + } - return ret; - } + return ret; + } }
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/DSUtils.h b/plugins/pluginDirectShow/internals/DSUtils.h index 09690ea..4d4cc97 100755 --- a/plugins/pluginDirectShow/internals/DSUtils.h +++ b/plugins/pluginDirectShow/internals/DSUtils.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ diff --git a/plugins/pluginDirectShow/internals/Resizer.cxx b/plugins/pluginDirectShow/internals/Resizer.cxx index 32bcfac..94db49e 100755 --- a/plugins/pluginDirectShow/internals/Resizer.cxx +++ b/plugins/pluginDirectShow/internals/Resizer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -33,19 +33,19 @@ #define STRETCH_2_1 7 void __stdcall StretchDIB( - LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of destination - LPVOID lpvDst, // --> to destination bits - int DstX, // Destination origin - x coordinate - int DstY, // Destination origin - y coordinate - int DstXE, // x extent of the BLT - int DstYE, // y extent of the BLT - LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of source - LPVOID lpvSrc, // --> to source bits - int SrcX, // Source origin - x coordinate - int SrcY, // Source origin - y coordinate - int SrcXE, // x extent of the BLT - int SrcYE // y extent of the BLT - ); + LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of destination + LPVOID lpvDst, // --> to destination bits + int DstX, // Destination origin - x coordinate + int DstY, // Destination origin - y coordinate + int DstXE, // x extent of the BLT + int DstYE, // y extent of the BLT + LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of source + LPVOID lpvSrc, // --> to source bits + int SrcX, // Source origin - x coordinate + int SrcY, // Source origin - y coordinate + int SrcXE, // x extent of the BLT + int SrcYE // y extent of the BLT +); /* * an X_FUNC is a function that copies one scanline, stretching or shrinking it @@ -63,10 +63,10 @@ void __stdcall StretchDIB( * the fraction is multiplied by 65536. */ typedef void (*X_FUNC) (LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract); + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract); void X_Stretch_1_1_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); @@ -97,23 +97,23 @@ void X_Stretch_N_1_32Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int */ void Y_Stretch_1_N(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract, - X_FUNC x_func, int nBits); + int DstYE, int SrcWidth, int DstWidth, int x_fract, + X_FUNC x_func, int nBits); void Y_Stretch_N_1(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract, - X_FUNC x_func); + int DstYE, int SrcWidth, int DstWidth, int x_fract, + X_FUNC x_func); /* * special case y-stretch functions for 1:2 in both dimensions for 8 and 16 bits * takes no X_FUNC arg. Will do entire stretch. */ void Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract); + int DstYE, int SrcWidth, int DstWidth, int x_fract); void Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract); + int DstYE, int SrcWidth, int DstWidth, int x_fract); /* straight copy of one scanline of count bytes */ void X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count); @@ -123,27 +123,27 @@ void X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count); // Resize function // void ResizeRGB( BITMAPINFOHEADER *pbiIn, //Src's BitMapInFoHeader - const unsigned char * dibBits, //Src bits - BITMAPINFOHEADER *pbiOut, - unsigned char *pFrame, //Dst bits - int iNewWidth, //new W in pixel - int iNewHeight) //new H in pixel -{ - StretchDIB( pbiOut, // --> BITMAPINFO of destination - pFrame, // --> to destination bits - 0, // Destination origin - x coordinate - 0, // Destination origin - y coordinate - iNewWidth, // x extent of the BLT - iNewHeight, // y extent of the BLT - pbiIn, // --> BITMAPINFO of destination - (void*) dibBits, // --> to source bits - 0, // Source origin - x coordinate - 0, // Source origin - y coordinate - pbiIn->biWidth, // x extent of the BLT - pbiIn->biHeight // y extent of the BLT - ); - - return; + const unsigned char * dibBits, //Src bits + BITMAPINFOHEADER *pbiOut, + unsigned char *pFrame, //Dst bits + int iNewWidth, //new W in pixel + int iNewHeight) //new H in pixel +{ + StretchDIB( pbiOut, // --> BITMAPINFO of destination + pFrame, // --> to destination bits + 0, // Destination origin - x coordinate + 0, // Destination origin - y coordinate + iNewWidth, // x extent of the BLT + iNewHeight, // y extent of the BLT + pbiIn, // --> BITMAPINFO of destination + (void*) dibBits, // --> to source bits + 0, // Source origin - x coordinate + 0, // Source origin - y coordinate + pbiIn->biWidth, // x extent of the BLT + pbiIn->biHeight // y extent of the BLT + ); + + return; } @@ -166,44 +166,49 @@ StretchFactor(int SrcE, int DstE, int *pfract) { - if (SrcE == DstE) { - if (pfract != NULL) { - pfract = 0; - } - - return(STRETCH_1_1); - - } - - - if (SrcE > DstE) { - if (pfract != NULL) { - *pfract = ( (DstE << 16) / SrcE) & 0xffff; - } - - if (SrcE == (DstE * 2)) { - return(STRETCH_2_1); - } else if (SrcE == (DstE * 4)) { - return(STRETCH_4_1); - } else { - return(STRETCH_N_1); - } - - } else { - - /* calculate delta fraction based on smallest / largest */ - if (pfract != NULL) { - *pfract = ( (SrcE << 16) / DstE) & 0xffff; - } - - if (DstE == (SrcE * 2)) { - return(STRETCH_1_2); - } else if (DstE == (SrcE * 4)) { - return(STRETCH_1_4); - } else { - return(STRETCH_1_N); - } - } + if (SrcE == DstE) { + if (pfract != NULL) { + pfract = 0; + } + + return(STRETCH_1_1); + + } + + + if (SrcE > DstE) { + if (pfract != NULL) { + *pfract = ( (DstE << 16) / SrcE) & 0xffff; + } + + if (SrcE == (DstE * 2)) { + return(STRETCH_2_1); + } + else if (SrcE == (DstE * 4)) { + return(STRETCH_4_1); + } + else { + return(STRETCH_N_1); + } + + } + else { + + /* calculate delta fraction based on smallest / largest */ + if (pfract != NULL) { + *pfract = ( (SrcE << 16) / DstE) & 0xffff; + } + + if (DstE == (SrcE * 2)) { + return(STRETCH_1_2); + } + else if (DstE == (SrcE * 4)) { + return(STRETCH_1_4); + } + else { + return(STRETCH_1_N); + } + } } @@ -216,226 +221,227 @@ StretchFactor(int SrcE, int DstE, int *pfract) void FAR PASCAL StretchDIB( - LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of destination - LPVOID lpvDst, // --> to destination bits - int DstX, // Destination origin - x coordinate - int DstY, // Destination origin - y coordinate - int DstXE, // x extent of the BLT - int DstYE, // y extent of the BLT - LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of source - LPVOID lpvSrc, // --> to source bits - int SrcX, // Source origin - x coordinate - int SrcY, // Source origin - y coordinate - int SrcXE, // x extent of the BLT - int SrcYE // y extent of the BLT - ) + LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of destination + LPVOID lpvDst, // --> to destination bits + int DstX, // Destination origin - x coordinate + int DstY, // Destination origin - y coordinate + int DstXE, // x extent of the BLT + int DstYE, // y extent of the BLT + LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of source + LPVOID lpvSrc, // --> to source bits + int SrcX, // Source origin - x coordinate + int SrcY, // Source origin - y coordinate + int SrcXE, // x extent of the BLT + int SrcYE // y extent of the BLT +) { - int nBits; - int SrcWidth, DstWidth; - LPBYTE lpDst = (LPBYTE)lpvDst, lpSrc = (LPBYTE)lpvSrc; - int x_fract; - int x_factor; - int y_factor; - X_FUNC xfunc; - - - /* - * chek that sizes are not same - */ - /*if(DstXE == SrcXE && DstYE == SrcYE) - { - return; - }*/ - /* - * check that bit depths are same and 8, 16 or 24 - */ - - if ((nBits = biDst->biBitCount) != biSrc->biBitCount) { - return; - } - - if ( (nBits != 8 ) && (nBits != 16) && (nBits != 24) && - (nBits != 32)) { - return; - } - - /* - * check that extents are not bad - */ - if ( (SrcXE <= 0) || (SrcYE <= 0) || (DstXE <= 0) || (DstYE <= 0)) { - return; - } - - /* - * calculate width of one scan line in bytes, rounded up to - * DWORD boundary. - */ - SrcWidth = (((biSrc->biWidth * nBits) + 31) & ~31) / 8; - DstWidth = (((biDst->biWidth * nBits) + 31) & ~31) / 8; - - /* - * set initial source and dest pointers - */ - lpSrc += (SrcY * SrcWidth) + ((SrcX * nBits) / 8); - lpDst += (DstY * DstWidth) + ((DstX * nBits) / 8); - - - /* - * calculate stretch proportions (1:1, 1:2, 1:N, N:1 etc) and - * also the fractional stretch factor. (we are not interested in - * the y stretch fraction - this is only used in x stretching. - */ - - y_factor = StretchFactor(SrcYE, DstYE, NULL); - x_factor = StretchFactor(SrcXE, DstXE, &x_fract); - - /* - * we have special case routines for 1:2 in both dimensions - * for 8 and 16 bits - */ - if ((y_factor == x_factor) && (y_factor == STRETCH_1_2)) { - - if (nBits == 8) { - //StartCounting(); - Stretch_1_2_8Bits(lpSrc, lpDst, SrcXE, SrcYE, - DstXE, DstYE, SrcWidth, DstWidth, - x_fract); - //EndCounting("8 bit"); - return; - - } else if (nBits == 16) { - //StartCounting(); - Stretch_1_2_16Bits(lpSrc, lpDst, SrcXE, SrcYE, - DstXE, DstYE, SrcWidth, DstWidth, - x_fract); - //EndCounting("16 bit"); - return; - } - } - - - /* pick an X stretch function */ - switch(nBits) { - - case 8: - switch(x_factor) { - case STRETCH_1_1: - xfunc = X_Stretch_1_1_8Bits; - break; - - case STRETCH_1_2: - xfunc = X_Stretch_1_2_8Bits; - break; - - case STRETCH_1_4: - xfunc = X_Stretch_1_4_8Bits; - break; - - case STRETCH_1_N: - xfunc = X_Stretch_1_N_8Bits; - break; - - case STRETCH_N_1: - case STRETCH_4_1: - case STRETCH_2_1: - xfunc = X_Stretch_N_1_8Bits; - break; - - } - break; - - case 16: - switch(x_factor) { - case STRETCH_1_1: - xfunc = X_Stretch_1_1_16Bits; - break; - - case STRETCH_1_2: - xfunc = X_Stretch_1_2_16Bits; - break; - - case STRETCH_1_4: - case STRETCH_1_N: - xfunc = X_Stretch_1_N_16Bits; - break; - - case STRETCH_N_1: - case STRETCH_4_1: - case STRETCH_2_1: - xfunc = X_Stretch_N_1_16Bits; - break; - - } - break; - - case 24: - switch(x_factor) { - case STRETCH_1_1: - xfunc = X_Stretch_1_1_24Bits; - break; - - case STRETCH_1_2: - case STRETCH_1_4: - case STRETCH_1_N: - xfunc = X_Stretch_1_N_24Bits; - break; - - case STRETCH_N_1: - case STRETCH_4_1: - case STRETCH_2_1: - xfunc = X_Stretch_N_1_24Bits; - break; - - } - break; - - case 32: - switch(x_factor) { - case STRETCH_1_1: - xfunc = X_Stretch_1_1_32Bits; - break; - - case STRETCH_1_2: - case STRETCH_1_4: - case STRETCH_1_N: - xfunc = X_Stretch_1_N_32Bits; - break; - - case STRETCH_N_1: - case STRETCH_4_1: - case STRETCH_2_1: - xfunc = X_Stretch_N_1_32Bits; - break; - - } - break; - - } - - - /* - * now call appropriate stretching function depending - * on the y stretch factor - */ - switch (y_factor) { - case STRETCH_1_1: - case STRETCH_1_2: - case STRETCH_1_4: - case STRETCH_1_N: - Y_Stretch_1_N(lpSrc, lpDst, SrcXE, SrcYE, - DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc, nBits); - break; - - case STRETCH_N_1: - case STRETCH_4_1: - case STRETCH_2_1: - Y_Stretch_N_1(lpSrc, lpDst, SrcXE, SrcYE, - DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc); - break; - - } - return; + int nBits; + int SrcWidth, DstWidth; + LPBYTE lpDst = (LPBYTE)lpvDst, lpSrc = (LPBYTE)lpvSrc; + int x_fract; + int x_factor; + int y_factor; + X_FUNC xfunc; + + + /* + * chek that sizes are not same + */ + /*if(DstXE == SrcXE && DstYE == SrcYE) + { + return; + }*/ + /* + * check that bit depths are same and 8, 16 or 24 + */ + + if ((nBits = biDst->biBitCount) != biSrc->biBitCount) { + return; + } + + if ( (nBits != 8 ) && (nBits != 16) && (nBits != 24) && + (nBits != 32)) { + return; + } + + /* + * check that extents are not bad + */ + if ( (SrcXE <= 0) || (SrcYE <= 0) || (DstXE <= 0) || (DstYE <= 0)) { + return; + } + + /* + * calculate width of one scan line in bytes, rounded up to + * DWORD boundary. + */ + SrcWidth = (((biSrc->biWidth * nBits) + 31) & ~31) / 8; + DstWidth = (((biDst->biWidth * nBits) + 31) & ~31) / 8; + + /* + * set initial source and dest pointers + */ + lpSrc += (SrcY * SrcWidth) + ((SrcX * nBits) / 8); + lpDst += (DstY * DstWidth) + ((DstX * nBits) / 8); + + + /* + * calculate stretch proportions (1:1, 1:2, 1:N, N:1 etc) and + * also the fractional stretch factor. (we are not interested in + * the y stretch fraction - this is only used in x stretching. + */ + + y_factor = StretchFactor(SrcYE, DstYE, NULL); + x_factor = StretchFactor(SrcXE, DstXE, &x_fract); + + /* + * we have special case routines for 1:2 in both dimensions + * for 8 and 16 bits + */ + if ((y_factor == x_factor) && (y_factor == STRETCH_1_2)) { + + if (nBits == 8) { + //StartCounting(); + Stretch_1_2_8Bits(lpSrc, lpDst, SrcXE, SrcYE, + DstXE, DstYE, SrcWidth, DstWidth, + x_fract); + //EndCounting("8 bit"); + return; + + } + else if (nBits == 16) { + //StartCounting(); + Stretch_1_2_16Bits(lpSrc, lpDst, SrcXE, SrcYE, + DstXE, DstYE, SrcWidth, DstWidth, + x_fract); + //EndCounting("16 bit"); + return; + } + } + + + /* pick an X stretch function */ + switch(nBits) { + + case 8: + switch(x_factor) { + case STRETCH_1_1: + xfunc = X_Stretch_1_1_8Bits; + break; + + case STRETCH_1_2: + xfunc = X_Stretch_1_2_8Bits; + break; + + case STRETCH_1_4: + xfunc = X_Stretch_1_4_8Bits; + break; + + case STRETCH_1_N: + xfunc = X_Stretch_1_N_8Bits; + break; + + case STRETCH_N_1: + case STRETCH_4_1: + case STRETCH_2_1: + xfunc = X_Stretch_N_1_8Bits; + break; + + } + break; + + case 16: + switch(x_factor) { + case STRETCH_1_1: + xfunc = X_Stretch_1_1_16Bits; + break; + + case STRETCH_1_2: + xfunc = X_Stretch_1_2_16Bits; + break; + + case STRETCH_1_4: + case STRETCH_1_N: + xfunc = X_Stretch_1_N_16Bits; + break; + + case STRETCH_N_1: + case STRETCH_4_1: + case STRETCH_2_1: + xfunc = X_Stretch_N_1_16Bits; + break; + + } + break; + + case 24: + switch(x_factor) { + case STRETCH_1_1: + xfunc = X_Stretch_1_1_24Bits; + break; + + case STRETCH_1_2: + case STRETCH_1_4: + case STRETCH_1_N: + xfunc = X_Stretch_1_N_24Bits; + break; + + case STRETCH_N_1: + case STRETCH_4_1: + case STRETCH_2_1: + xfunc = X_Stretch_N_1_24Bits; + break; + + } + break; + + case 32: + switch(x_factor) { + case STRETCH_1_1: + xfunc = X_Stretch_1_1_32Bits; + break; + + case STRETCH_1_2: + case STRETCH_1_4: + case STRETCH_1_N: + xfunc = X_Stretch_1_N_32Bits; + break; + + case STRETCH_N_1: + case STRETCH_4_1: + case STRETCH_2_1: + xfunc = X_Stretch_N_1_32Bits; + break; + + } + break; + + } + + + /* + * now call appropriate stretching function depending + * on the y stretch factor + */ + switch (y_factor) { + case STRETCH_1_1: + case STRETCH_1_2: + case STRETCH_1_4: + case STRETCH_1_N: + Y_Stretch_1_N(lpSrc, lpDst, SrcXE, SrcYE, + DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc, nBits); + break; + + case STRETCH_N_1: + case STRETCH_4_1: + case STRETCH_2_1: + Y_Stretch_N_1(lpSrc, lpDst, SrcXE, SrcYE, + DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc); + break; + + } + return; } @@ -456,49 +462,50 @@ StretchDIB( void Y_Stretch_1_N(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int SrcYE, - int DstXE, - int DstYE, - int SrcWidth, - int DstWidth, - int x_fract, - X_FUNC x_func, - int nBits) + LPBYTE lpDst, + int SrcXE, + int SrcYE, + int DstXE, + int DstYE, + int SrcWidth, + int DstWidth, + int x_fract, + X_FUNC x_func, + int nBits) { - int ydelta; - register int i; - LPBYTE lpPrev = NULL; - - ydelta = DstYE -1; - - for (i = 0; i < DstYE; i++) { - - /* have we already stretched this scanline ? */ - if (lpPrev == NULL) { - /* no - copy one scanline */ - (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract); - lpPrev = lpDst; - } else { - /* yes - this is a duplicate scanline. do - * a straight copy of one that has already - * been stretched/shrunk - */ - X_CopyScanline(lpPrev, lpDst, DstXE * nBits / 8); - } - - /* advance dest pointer */ - lpDst += DstWidth; - - /* should we advance source pointer this time ? */ - if ( (ydelta -= SrcYE) < 0) { - ydelta += DstYE; - lpSrc += SrcWidth; - lpPrev = NULL; - } - } + int ydelta; + register int i; + LPBYTE lpPrev = NULL; + + ydelta = DstYE -1; + + for (i = 0; i < DstYE; i++) { + + /* have we already stretched this scanline ? */ + if (lpPrev == NULL) { + /* no - copy one scanline */ + (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract); + lpPrev = lpDst; + } + else { + /* yes - this is a duplicate scanline. do + * a straight copy of one that has already + * been stretched/shrunk + */ + X_CopyScanline(lpPrev, lpDst, DstXE * nBits / 8); + } + + /* advance dest pointer */ + lpDst += DstWidth; + + /* should we advance source pointer this time ? */ + if ( (ydelta -= SrcYE) < 0) { + ydelta += DstYE; + lpSrc += SrcWidth; + lpPrev = NULL; + } + } } @@ -510,38 +517,39 @@ Y_Stretch_1_N(LPBYTE lpSrc, */ void Y_Stretch_N_1(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int SrcYE, - int DstXE, - int DstYE, - int SrcWidth, - int DstWidth, - int x_fract, - X_FUNC x_func) + LPBYTE lpDst, + int SrcXE, + int SrcYE, + int DstXE, + int DstYE, + int SrcWidth, + int DstWidth, + int x_fract, + X_FUNC x_func) { - int ydelta; - register int i; + int ydelta; + register int i; - ydelta = SrcYE -1; + ydelta = SrcYE -1; - for (i = 0; i < DstYE; i++) { + for (i = 0; i < DstYE; i++) { - /* copy one scanline */ - (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract); + /* copy one scanline */ + (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract); - /* advance dest pointer */ - lpDst += DstWidth; + /* advance dest pointer */ + lpDst += DstWidth; - /* how many times do we advance source pointer this time ? */ - do { - lpSrc += SrcWidth; - ydelta -= DstYE; - } while (ydelta >= 0); + /* how many times do we advance source pointer this time ? */ + do { + lpSrc += SrcWidth; + ydelta -= DstYE; + } + while (ydelta >= 0); - ydelta += SrcYE; - } + ydelta += SrcYE; + } } /* ---8-bit X stretching -------------------------------------------------- */ @@ -553,27 +561,27 @@ Y_Stretch_N_1(LPBYTE lpSrc, */ void X_Stretch_1_N_8Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = DstXE -1; + xdelta = DstXE -1; - for (i = 0; i < DstXE; i++) { + for (i = 0; i < DstXE; i++) { - /* copy one byte and advance dest */ - *lpDst++ = *lpSrc; + /* copy one byte and advance dest */ + *lpDst++ = *lpSrc; - /* should we advance source pointer this time ? */ - if ( (xdelta -= SrcXE) < 0) { - xdelta += DstXE; - lpSrc++; - } - } + /* should we advance source pointer this time ? */ + if ( (xdelta -= SrcXE) < 0) { + xdelta += DstXE; + lpSrc++; + } + } } @@ -584,29 +592,30 @@ X_Stretch_1_N_8Bits(LPBYTE lpSrc, */ void X_Stretch_N_1_8Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = SrcXE -1; + xdelta = SrcXE -1; - for (i = 0; i < DstXE; i++) { + for (i = 0; i < DstXE; i++) { - /* copy one byte and advance dest */ - *lpDst++ = *lpSrc; + /* copy one byte and advance dest */ + *lpDst++ = *lpSrc; - /* how many times do we advance source pointer this time ? */ - do { - lpSrc++; - xdelta -= DstXE; - } while (xdelta >= 0); + /* how many times do we advance source pointer this time ? */ + do { + lpSrc++; + xdelta -= DstXE; + } + while (xdelta >= 0); - xdelta += SrcXE; - } + xdelta += SrcXE; + } } /* @@ -616,51 +625,52 @@ X_Stretch_N_1_8Bits(LPBYTE lpSrc, void X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count) { - register int i; - - /* - * if the alignment of lpSrc and lpDst is the same, then - * we can get them aligned and do a faster copy - */ - if (((DWORD_PTR) lpSrc & 0x3) == ( (DWORD_PTR) lpDst & 0x3)) { - - /* align on WORD boundary */ - if ( (DWORD_PTR) lpSrc & 0x1) { - *lpDst++ = *lpSrc++; - count--; - } - - /* align on DWORD boundary */ - if ((DWORD_PTR) lpSrc & 0x2) { - * ((LPWORD) lpDst) = *((LPWORD) lpSrc); - lpDst += sizeof(WORD); - lpSrc += sizeof(WORD); - count -= sizeof(WORD); - } - - /* copy whole DWORDS */ - for ( i = (count / 4); i > 0; i--) { - *((LPDWORD) lpDst) = *((LPDWORD) lpSrc); - lpSrc += sizeof(DWORD); - lpDst += sizeof(DWORD); - } - } else { - /* the lpSrc and lpDst pointers are different - * alignment, so leave them unaligned and - * copy all the whole DWORDs - */ - for (i = (count / 4); i> 0; i--) { - *( (DWORD UNALIGNED FAR *) lpDst) = - *((DWORD UNALIGNED FAR *) lpSrc); - lpSrc += sizeof(DWORD); - lpDst += sizeof(DWORD); - } - } - - /* in either case, copy last (up to 3) bytes. */ - for ( i = count % 4; i > 0; i--) { - *lpDst++ = *lpSrc++; - } + register int i; + + /* + * if the alignment of lpSrc and lpDst is the same, then + * we can get them aligned and do a faster copy + */ + if (((DWORD_PTR) lpSrc & 0x3) == ( (DWORD_PTR) lpDst & 0x3)) { + + /* align on WORD boundary */ + if ( (DWORD_PTR) lpSrc & 0x1) { + *lpDst++ = *lpSrc++; + count--; + } + + /* align on DWORD boundary */ + if ((DWORD_PTR) lpSrc & 0x2) { + * ((LPWORD) lpDst) = *((LPWORD) lpSrc); + lpDst += sizeof(WORD); + lpSrc += sizeof(WORD); + count -= sizeof(WORD); + } + + /* copy whole DWORDS */ + for ( i = (count / 4); i > 0; i--) { + *((LPDWORD) lpDst) = *((LPDWORD) lpSrc); + lpSrc += sizeof(DWORD); + lpDst += sizeof(DWORD); + } + } + else { + /* the lpSrc and lpDst pointers are different + * alignment, so leave them unaligned and + * copy all the whole DWORDs + */ + for (i = (count / 4); i> 0; i--) { + *( (DWORD UNALIGNED FAR *) lpDst) = + *((DWORD UNALIGNED FAR *) lpSrc); + lpSrc += sizeof(DWORD); + lpDst += sizeof(DWORD); + } + } + + /* in either case, copy last (up to 3) bytes. */ + for ( i = count % 4; i > 0; i--) { + *lpDst++ = *lpSrc++; + } } /* @@ -670,13 +680,13 @@ X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count) */ void X_Stretch_1_1_8Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - X_CopyScanline(lpSrc, lpDst, DstXE); + X_CopyScanline(lpSrc, lpDst, DstXE); } @@ -687,22 +697,22 @@ X_Stretch_1_1_8Bits(LPBYTE lpSrc, */ void X_Stretch_1_2_8Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - WORD wPix; - register int i; + WORD wPix; + register int i; - for (i = 0; i < SrcXE; i++) { + for (i = 0; i < SrcXE; i++) { - /* get a pixel and double it */ - wPix = *lpSrc++; - wPix |= (wPix << 8); - * ((WORD UNALIGNED *) lpDst) = wPix; - lpDst += sizeof(WORD); - } + /* get a pixel and double it */ + wPix = *lpSrc++; + wPix |= (wPix << 8); + * ((WORD UNALIGNED *) lpDst) = wPix; + lpDst += sizeof(WORD); + } } @@ -713,23 +723,23 @@ X_Stretch_1_2_8Bits(LPBYTE lpSrc, */ void X_Stretch_1_4_8Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - DWORD dwPix; - register int i; - - for (i = 0; i < SrcXE; i++) { - - /* get a pixel and make four copies of it */ - dwPix = *lpSrc++; - dwPix |= (dwPix <<8); - dwPix |= (dwPix << 16); - * ((DWORD UNALIGNED *) lpDst) = dwPix; - lpDst += sizeof(DWORD); - } + DWORD dwPix; + register int i; + + for (i = 0; i < SrcXE; i++) { + + /* get a pixel and make four copies of it */ + dwPix = *lpSrc++; + dwPix |= (dwPix <<8); + dwPix |= (dwPix << 16); + * ((DWORD UNALIGNED *) lpDst) = dwPix; + lpDst += sizeof(DWORD); + } } @@ -740,13 +750,13 @@ X_Stretch_1_4_8Bits(LPBYTE lpSrc, */ void X_Stretch_1_1_16Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - X_CopyScanline(lpSrc, lpDst, DstXE * sizeof(WORD)); + X_CopyScanline(lpSrc, lpDst, DstXE * sizeof(WORD)); } @@ -756,25 +766,25 @@ X_Stretch_1_1_16Bits(LPBYTE lpSrc, */ void X_Stretch_1_2_16Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - DWORD dwPix; - register int i; + DWORD dwPix; + register int i; - for (i = 0; i < SrcXE; i++) { + for (i = 0; i < SrcXE; i++) { - /* get a pixel and double it */ - dwPix = * ((WORD *)lpSrc); - dwPix |= (dwPix << 16); - * ((DWORD UNALIGNED *) lpDst) = dwPix; + /* get a pixel and double it */ + dwPix = * ((WORD *)lpSrc); + dwPix |= (dwPix << 16); + * ((DWORD UNALIGNED *) lpDst) = dwPix; - lpDst += sizeof(DWORD); - lpSrc += sizeof(WORD); - } + lpDst += sizeof(DWORD); + lpSrc += sizeof(WORD); + } } @@ -783,29 +793,29 @@ X_Stretch_1_2_16Bits(LPBYTE lpSrc, */ void X_Stretch_1_N_16Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = DstXE -1; + xdelta = DstXE -1; - for (i = 0; i < DstXE; i++) { + for (i = 0; i < DstXE; i++) { - /* copy one pixel and advance dest */ - *((WORD *) lpDst) = *((WORD *) lpSrc); + /* copy one pixel and advance dest */ + *((WORD *) lpDst) = *((WORD *) lpSrc); - lpDst += sizeof(WORD); + lpDst += sizeof(WORD); - /* should we advance source pointer this time ? */ - if ( (xdelta -= SrcXE) < 0) { - xdelta += DstXE; - lpSrc += sizeof(WORD); - } - } + /* should we advance source pointer this time ? */ + if ( (xdelta -= SrcXE) < 0) { + xdelta += DstXE; + lpSrc += sizeof(WORD); + } + } } /* @@ -813,32 +823,33 @@ X_Stretch_1_N_16Bits(LPBYTE lpSrc, */ void X_Stretch_N_1_16Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = SrcXE -1; + xdelta = SrcXE -1; - for (i = 0; i < DstXE; i++) { + for (i = 0; i < DstXE; i++) { - /* copy one pixel and advance dest */ - *((WORD *) lpDst) = *((WORD *)lpSrc); + /* copy one pixel and advance dest */ + *((WORD *) lpDst) = *((WORD *)lpSrc); - lpDst += sizeof(WORD); + lpDst += sizeof(WORD); - /* how many times do we advance source pointer this time ? */ - do { - lpSrc += sizeof(WORD); - xdelta -= DstXE; - } while (xdelta >= 0); + /* how many times do we advance source pointer this time ? */ + do { + lpSrc += sizeof(WORD); + xdelta -= DstXE; + } + while (xdelta >= 0); - xdelta += SrcXE; - } + xdelta += SrcXE; + } } @@ -850,12 +861,12 @@ X_Stretch_N_1_16Bits(LPBYTE lpSrc, */ void X_Stretch_1_1_24Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - X_CopyScanline(lpSrc, lpDst, DstXE * 3); + X_CopyScanline(lpSrc, lpDst, DstXE * 3); } /* @@ -863,32 +874,32 @@ X_Stretch_1_1_24Bits(LPBYTE lpSrc, */ void X_Stretch_1_N_24Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = DstXE -1; + xdelta = DstXE -1; - for (i = 0; i < DstXE; i++) { - /* copy first word of pixel and advance dest */ - *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc); + for (i = 0; i < DstXE; i++) { + /* copy first word of pixel and advance dest */ + *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc); - lpDst += sizeof(WORD); + lpDst += sizeof(WORD); - /* copy third byte and advance dest */ - *lpDst++ = lpSrc[sizeof(WORD)]; + /* copy third byte and advance dest */ + *lpDst++ = lpSrc[sizeof(WORD)]; - /* should we advance source pointer this time ? */ - if ( (xdelta -= SrcXE) < 0) { - xdelta += DstXE; - lpSrc += 3; - } - } + /* should we advance source pointer this time ? */ + if ( (xdelta -= SrcXE) < 0) { + xdelta += DstXE; + lpSrc += 3; + } + } } /* @@ -896,36 +907,37 @@ X_Stretch_1_N_24Bits(LPBYTE lpSrc, */ void X_Stretch_N_1_24Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - xdelta = SrcXE -1; + xdelta = SrcXE -1; - for (i = 0; i < DstXE; i++) { + for (i = 0; i < DstXE; i++) { - /* copy first word of pixel and advance dest */ - *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc); + /* copy first word of pixel and advance dest */ + *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc); - lpDst += sizeof(WORD); + lpDst += sizeof(WORD); - /* copy third byte and advance dest */ - *lpDst++ = lpSrc[sizeof(WORD)]; + /* copy third byte and advance dest */ + *lpDst++ = lpSrc[sizeof(WORD)]; - /* how many times do we advance source pointer this time ? */ - do { - lpSrc += 3; - xdelta -= DstXE; - } while (xdelta >= 0); + /* how many times do we advance source pointer this time ? */ + do { + lpSrc += 3; + xdelta -= DstXE; + } + while (xdelta >= 0); - xdelta += SrcXE; - } -} + xdelta += SrcXE; + } +} /* 32-bits ---------------------------------------------------------*/ @@ -935,12 +947,12 @@ X_Stretch_N_1_24Bits(LPBYTE lpSrc, */ void X_Stretch_1_1_32Bits(LPBYTE lpSrc, - LPBYTE lpDst, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst, + int SrcXE, + int DstXE, + int x_fract) { - X_CopyScanline((BYTE*) lpSrc, (BYTE*) lpDst, DstXE * sizeof( RGBQUAD ) ); + X_CopyScanline((BYTE*) lpSrc, (BYTE*) lpDst, DstXE * sizeof( RGBQUAD ) ); } /* @@ -948,34 +960,32 @@ X_Stretch_1_1_32Bits(LPBYTE lpSrc, */ void X_Stretch_1_N_32Bits(LPBYTE lpSrc0, - LPBYTE lpDst0, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst0, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - RGBQUAD *lpSrc=(RGBQUAD *)lpSrc0; - RGBQUAD *lpDst=(RGBQUAD *)lpDst0; + RGBQUAD *lpSrc=(RGBQUAD *)lpSrc0; + RGBQUAD *lpDst=(RGBQUAD *)lpDst0; - xdelta = DstXE -1; + xdelta = DstXE -1; - for (i = 0; i < DstXE; i++) - { - /* copy first word of pixel and advance dest */ - *lpDst = *lpSrc; - lpDst++; + for (i = 0; i < DstXE; i++) { + /* copy first word of pixel and advance dest */ + *lpDst = *lpSrc; + lpDst++; - /* should we advance source pointer this time ? */ - if ( (xdelta -= SrcXE) < 0) - { - xdelta += DstXE; - lpSrc++; - } - } + /* should we advance source pointer this time ? */ + if ( (xdelta -= SrcXE) < 0) { + xdelta += DstXE; + lpSrc++; + } + } } /* @@ -983,34 +993,33 @@ X_Stretch_1_N_32Bits(LPBYTE lpSrc0, */ void X_Stretch_N_1_32Bits(LPBYTE lpSrc0, - LPBYTE lpDst0, - int SrcXE, - int DstXE, - int x_fract) + LPBYTE lpDst0, + int SrcXE, + int DstXE, + int x_fract) { - int xdelta; - register int i; + int xdelta; + register int i; - RGBQUAD *lpSrc=(RGBQUAD *)lpSrc0; - RGBQUAD *lpDst=(RGBQUAD *)lpDst0; + RGBQUAD *lpSrc=(RGBQUAD *)lpSrc0; + RGBQUAD *lpDst=(RGBQUAD *)lpDst0; - xdelta = SrcXE -1; + xdelta = SrcXE -1; - for (i = 0; i < DstXE; i++) - { - *lpDst = *lpSrc; - lpDst++; + for (i = 0; i < DstXE; i++) { + *lpDst = *lpSrc; + lpDst++; - /* how many times do we advance source pointer this time ? */ - do - { - lpSrc++; - xdelta -= DstXE; - } while (xdelta >= 0); + /* how many times do we advance source pointer this time ? */ + do { + lpSrc++; + xdelta -= DstXE; + } + while (xdelta >= 0); - xdelta += SrcXE; - } -} + xdelta += SrcXE; + } +} @@ -1026,116 +1035,116 @@ X_Stretch_N_1_32Bits(LPBYTE lpSrc0, */ void Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract) + int DstYE, int SrcWidth, int DstWidth, int x_fract) { - int SrcInc, DstInc; - register int i, j; - WORD wPix; - DWORD dwPix4; + int SrcInc, DstInc; + register int i, j; + WORD wPix; + DWORD dwPix4; - /* amount to advance source by at the end of each scan */ - SrcInc = SrcWidth - SrcXE; + /* amount to advance source by at the end of each scan */ + SrcInc = SrcWidth - SrcXE; - /* amount to advance dest by at the end of each scan - note - * that we write two scans at once, so advance past the next - * scan line - */ - DstInc = (DstWidth * 2) - DstXE; + /* amount to advance dest by at the end of each scan - note + * that we write two scans at once, so advance past the next + * scan line + */ + DstInc = (DstWidth * 2) - DstXE; - /* - * we would like to copy the pixels DWORD at a time. this means - * being aligned. if we are currently aligned on a WORD boundary, - * then copy one pixel to get aligned. If we are on a byte - * boundary, we can never get aligned, so use the slower loop. - */ - if ( ((DWORD_PTR)lpDst) & 1) { + /* + * we would like to copy the pixels DWORD at a time. this means + * being aligned. if we are currently aligned on a WORD boundary, + * then copy one pixel to get aligned. If we are on a byte + * boundary, we can never get aligned, so use the slower loop. + */ + if ( ((DWORD_PTR)lpDst) & 1) { - /* - * dest is byte aligned - so we can never align it - * by writing WORDs - use slow loop. - */ - for (i = 0; i < SrcYE; i++) { + /* + * dest is byte aligned - so we can never align it + * by writing WORDs - use slow loop. + */ + for (i = 0; i < SrcYE; i++) { - for (j = 0; j < SrcXE; j++) { + for (j = 0; j < SrcXE; j++) { - /* get a pixel and double it */ + /* get a pixel and double it */ - wPix = *lpSrc++; - wPix |= (wPix<<8); + wPix = *lpSrc++; + wPix |= (wPix<<8); - /* write doubled pixel to this scanline */ + /* write doubled pixel to this scanline */ - *( (WORD UNALIGNED *) lpDst) = wPix; + *( (WORD UNALIGNED *) lpDst) = wPix; - /* write double pixel to next scanline */ - *( (WORD UNALIGNED *) (lpDst + DstWidth)) = wPix; + /* write double pixel to next scanline */ + *( (WORD UNALIGNED *) (lpDst + DstWidth)) = wPix; - lpDst += sizeof(WORD); - } - lpSrc += SrcInc; - lpDst += DstInc; - } - return; - } + lpDst += sizeof(WORD); + } + lpSrc += SrcInc; + lpDst += DstInc; + } + return; + } - /* - * this will be the aligned version. align each scan line - */ - for ( i = 0; i < SrcYE; i++) { + /* + * this will be the aligned version. align each scan line + */ + for ( i = 0; i < SrcYE; i++) { - /* count of pixels remaining */ - j = SrcXE; + /* count of pixels remaining */ + j = SrcXE; - /* align this scan line */ - if (((DWORD_PTR)lpDst) & 2) { + /* align this scan line */ + if (((DWORD_PTR)lpDst) & 2) { - /* word aligned - copy one doubled pixel and we are ok */ - wPix = *lpSrc++; - wPix |= (wPix << 8); + /* word aligned - copy one doubled pixel and we are ok */ + wPix = *lpSrc++; + wPix |= (wPix << 8); - *( (WORD *) lpDst) = wPix; - *( (WORD *) (lpDst + DstWidth)) = wPix; - lpDst += sizeof(WORD); + *( (WORD *) lpDst) = wPix; + *( (WORD *) (lpDst + DstWidth)) = wPix; + lpDst += sizeof(WORD); - j -= 1; - } + j -= 1; + } - /* now dest is aligned - so loop eating two pixels at a time - * until there is at most one left - */ - for ( ; j > 1; j -= 2) { + /* now dest is aligned - so loop eating two pixels at a time + * until there is at most one left + */ + for ( ; j > 1; j -= 2) { - /* read two pixels and double them */ - wPix = * ((WORD UNALIGNED *) lpSrc); - lpSrc += sizeof(WORD); + /* read two pixels and double them */ + wPix = * ((WORD UNALIGNED *) lpSrc); + lpSrc += sizeof(WORD); - dwPix4 = (wPix & 0xff) | ((wPix & 0xff) << 8); - dwPix4 |= ((wPix & 0xff00) << 8) | ((wPix & 0xff00) << 16); - *((DWORD *) lpDst) = dwPix4; - *((DWORD *) (lpDst + DstWidth)) = dwPix4; + dwPix4 = (wPix & 0xff) | ((wPix & 0xff) << 8); + dwPix4 |= ((wPix & 0xff00) << 8) | ((wPix & 0xff00) << 16); + *((DWORD *) lpDst) = dwPix4; + *((DWORD *) (lpDst + DstWidth)) = dwPix4; - lpDst += sizeof(DWORD); - } + lpDst += sizeof(DWORD); + } - /* odd byte remaining ? */ - if (j > 0) { - /* word aligned - copy one doubled pixel and we are ok */ - wPix = *lpSrc++; - wPix |= (wPix << 8); + /* odd byte remaining ? */ + if (j > 0) { + /* word aligned - copy one doubled pixel and we are ok */ + wPix = *lpSrc++; + wPix |= (wPix << 8); - *( (WORD *) lpDst) = wPix; - *( (WORD *) (lpDst + DstWidth)) = wPix; - lpDst += sizeof(WORD); + *( (WORD *) lpDst) = wPix; + *( (WORD *) (lpDst + DstWidth)) = wPix; + lpDst += sizeof(WORD); - j -= 1; - } - lpSrc += SrcInc; - lpDst += DstInc; - } + j -= 1; + } + lpSrc += SrcInc; + lpDst += DstInc; + } } @@ -1148,45 +1157,45 @@ Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, void Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, - int DstYE, int SrcWidth, int DstWidth, int x_fract) + int DstYE, int SrcWidth, int DstWidth, int x_fract) { - int SrcInc, DstInc; - register int i, j; - DWORD dwPix; + int SrcInc, DstInc; + register int i, j; + DWORD dwPix; - /* amount to advance source by at the end of each scan */ - SrcInc = SrcWidth - (SrcXE * sizeof(WORD)); + /* amount to advance source by at the end of each scan */ + SrcInc = SrcWidth - (SrcXE * sizeof(WORD)); - /* amount to advance dest by at the end of each scan - note - * that we write two scans at once, so advance past the next - * scan line - */ - DstInc = (DstWidth * 2) - (DstXE * sizeof(WORD)); + /* amount to advance dest by at the end of each scan - note + * that we write two scans at once, so advance past the next + * scan line + */ + DstInc = (DstWidth * 2) - (DstXE * sizeof(WORD)); - for (i = 0; i < SrcYE; i++) { + for (i = 0; i < SrcYE; i++) { - for (j = 0; j < SrcXE; j++) { + for (j = 0; j < SrcXE; j++) { - /* get a pixel and double it */ + /* get a pixel and double it */ - dwPix = *((WORD *)lpSrc); - dwPix |= (dwPix<<16); + dwPix = *((WORD *)lpSrc); + dwPix |= (dwPix<<16); - lpSrc += sizeof(WORD); + lpSrc += sizeof(WORD); - /* write doubled pixel to this scanline */ + /* write doubled pixel to this scanline */ - *( (DWORD UNALIGNED *) lpDst) = dwPix; + *( (DWORD UNALIGNED *) lpDst) = dwPix; - /* write double pixel to next scanline */ - *( (DWORD UNALIGNED *) (lpDst + DstWidth)) = dwPix; + /* write double pixel to next scanline */ + *( (DWORD UNALIGNED *) (lpDst + DstWidth)) = dwPix; - lpDst += sizeof(DWORD); - } - lpSrc += SrcInc; - lpDst += DstInc; + lpDst += sizeof(DWORD); + } + lpSrc += SrcInc; + lpDst += DstInc; - } + } } diff --git a/plugins/pluginDirectShow/internals/Resizer.h b/plugins/pluginDirectShow/internals/Resizer.h index 6c76970..e91b980 100755 --- a/plugins/pluginDirectShow/internals/Resizer.h +++ b/plugins/pluginDirectShow/internals/Resizer.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -67,10 +67,10 @@ void ResizeRGB( BITMAPINFOHEADER *pbiIn, //Src's BitMapInFoHeader - const unsigned char * dibBits, //Src bits - BITMAPINFOHEADER *pbiOut, - unsigned char *pFrame, //Dst bits - int iNewWidth, //new W in pixel - int iNewHeight); //new H in pixel + const unsigned char * dibBits, //Src bits + BITMAPINFOHEADER *pbiOut, + unsigned char *pFrame, //Dst bits + int iNewWidth, //new W in pixel + int iNewHeight); //new H in pixel #endif //RESIZER_H diff --git a/plugins/pluginDirectShow/internals/VideoDisplayName.cxx b/plugins/pluginDirectShow/internals/VideoDisplayName.cxx index 6b4d0b0..ba71428 100755 --- a/plugins/pluginDirectShow/internals/VideoDisplayName.cxx +++ b/plugins/pluginDirectShow/internals/VideoDisplayName.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -23,15 +23,15 @@ VideoDisplayName::VideoDisplayName(std::string name_, std::string descr) : name( std::string VideoDisplayName::getName() const { - return this->name; + return this->name; } std::string VideoDisplayName::getDescription() const { - return this->description; + return this->description; } int VideoDisplayName::operator==(const VideoDisplayName &dev) const { - return this->name == dev.name; + return this->name == dev.name; } diff --git a/plugins/pluginDirectShow/internals/VideoDisplayName.h b/plugins/pluginDirectShow/internals/VideoDisplayName.h index 82dc0d0..34914b7 100755 --- a/plugins/pluginDirectShow/internals/VideoDisplayName.h +++ b/plugins/pluginDirectShow/internals/VideoDisplayName.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -25,19 +25,19 @@ class VideoDisplayName { public: - VideoDisplayName() {} + VideoDisplayName() {} - VideoDisplayName(std::string name, std::string description); + VideoDisplayName(std::string name, std::string description); - std::string getName() const; + std::string getName() const; - std::string getDescription() const; + std::string getDescription() const; - int operator==( const VideoDisplayName &dev ) const; + int operator==( const VideoDisplayName &dev ) const; private: - std::string name; - std::string description; + std::string name; + std::string description; }; #endif /* PLUGIN_DSHOW_VIDEODISPLAYNAME_H */ diff --git a/plugins/pluginDirectShow/internals/VideoFrame.h b/plugins/pluginDirectShow/internals/VideoFrame.h index 2c910a6..d9a7a9f 100755 --- a/plugins/pluginDirectShow/internals/VideoFrame.h +++ b/plugins/pluginDirectShow/internals/VideoFrame.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -19,20 +19,19 @@ #define PLUGIN_DSHOW_VIDEOFRAME_H // Define supported video formats -typedef enum _VIDEOFORMAT -{ - VIDEOFORMAT_NULL = 0, // 0 x 0 : Null - VIDEOFORMAT_SQCIF, // 128 x 96 : SQCIF - VIDEOFORMAT_QCIF, // 176 x 144 : QCIF - VIDEOFORMAT_QVGA, // 320 x 240 : QVGA - VIDEOFORMAT_CIF, // 352 x 288 : CIF - VIDEOFORMAT_IOS_MEDIUM, // 480 x 360 : IOS_MEDIUM - VIDEOFORMAT_VGA, // 640 x 480 : VGA - VIDEOFORMAT_4CIF, // 704 x 576 : 4CIF - VIDEOFORMAT_SVGA, // 800 x 600 : SVGA - VIDEOFORMAT_XGA, // 1024 x 768 : XGA - VIDEOFORMAT_SXGA, // 1280 x 1024 : SXGA - VIDEOFORMAT_16CIF, // 1408 x 1152 : 16CIF +typedef enum _VIDEOFORMAT { + VIDEOFORMAT_NULL = 0, // 0 x 0 : Null + VIDEOFORMAT_SQCIF, // 128 x 96 : SQCIF + VIDEOFORMAT_QCIF, // 176 x 144 : QCIF + VIDEOFORMAT_QVGA, // 320 x 240 : QVGA + VIDEOFORMAT_CIF, // 352 x 288 : CIF + VIDEOFORMAT_IOS_MEDIUM, // 480 x 360 : IOS_MEDIUM + VIDEOFORMAT_VGA, // 640 x 480 : VGA + VIDEOFORMAT_4CIF, // 704 x 576 : 4CIF + VIDEOFORMAT_SVGA, // 800 x 600 : SVGA + VIDEOFORMAT_XGA, // 1024 x 768 : XGA + VIDEOFORMAT_SXGA, // 1280 x 1024 : SXGA + VIDEOFORMAT_16CIF, // 1408 x 1152 : 16CIF } VIDEOFORMAT; @@ -54,7 +53,7 @@ typedef enum _VIDEOFORMAT case VIDEOFORMAT_NULL: \ default: width = 0; height = 0; break; \ } \ - + // Macro to get a video format from its size #define SIZE_TO_VIDEOFORMAT(width, height, format) \ @@ -70,7 +69,7 @@ typedef enum _VIDEOFORMAT else if ((width == 1280) && (height = 1024)) format = VIDEOFORMAT_SXGA; \ else if ((width == 1408) && (height = 1152)) format = VIDEOFORMAT_16CIF; \ else format = VIDEOFORMAT_NULL; \ - + // Constants for consumer and producer Ids #define GRABBER_VIDEO_ID 0x1FFFFFFF @@ -80,28 +79,52 @@ typedef enum _VIDEOFORMAT class VideoFrame { public: - VideoFrame() { this->data = NULL; }; - virtual ~VideoFrame() { if(this->data) { this->data = NULL;} }; + VideoFrame() { + this->data = NULL; + }; + virtual ~VideoFrame() { + if(this->data) { + this->data = NULL; + } + }; - int getWidth() { return this->width; }; - int getHeight() { return this->height; }; - int getBitsPerPixel() { return this->bpp; }; - int getTotalBits () { return this->width * this->height * (this->bpp/8); }; - void* getData() { return this->data; }; + int getWidth() { + return this->width; + }; + int getHeight() { + return this->height; + }; + int getBitsPerPixel() { + return this->bpp; + }; + int getTotalBits () { + return this->width * this->height * (this->bpp/8); + }; + void* getData() { + return this->data; + }; - void setWidth(int width_) { this->width = width_; }; - void setHeight(int height_) { this->height = height_; }; - void setBitsPerPixel( int bpp_) { this->bpp = bpp_; }; - void setData( void* data_) { this->data = data_; }; + void setWidth(int width_) { + this->width = width_; + }; + void setHeight(int height_) { + this->height = height_; + }; + void setBitsPerPixel( int bpp_) { + this->bpp = bpp_; + }; + void setData( void* data_) { + this->data = data_; + }; - VIDEOFORMAT getSize(); - void setSize(VIDEOFORMAT format); + VIDEOFORMAT getSize(); + void setSize(VIDEOFORMAT format); private: - void *data; - int width; - int height; - int bpp; + void *data; + int width; + int height; + int bpp; }; #endif /* VIDEOFRAME_H */ diff --git a/plugins/pluginDirectShow/internals/VideoGrabberName.cxx b/plugins/pluginDirectShow/internals/VideoGrabberName.cxx index 4b418cf..dd681c2 100755 --- a/plugins/pluginDirectShow/internals/VideoGrabberName.cxx +++ b/plugins/pluginDirectShow/internals/VideoGrabberName.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -23,15 +23,15 @@ VideoGrabberName::VideoGrabberName(std::string name_, std::string descr) : name( std::string VideoGrabberName::getName() const { - return this->name; + return this->name; } std::string VideoGrabberName::getDescription() const { - return this->description; + return this->description; } int VideoGrabberName::operator==(const VideoGrabberName &dev) const { - return this->name == dev.name; + return this->name == dev.name; }
\ No newline at end of file diff --git a/plugins/pluginDirectShow/internals/VideoGrabberName.h b/plugins/pluginDirectShow/internals/VideoGrabberName.h index 0bb45b5..aaf7d75 100755 --- a/plugins/pluginDirectShow/internals/VideoGrabberName.h +++ b/plugins/pluginDirectShow/internals/VideoGrabberName.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -25,19 +25,19 @@ class VideoGrabberName { public: - VideoGrabberName() {} + VideoGrabberName() {} - VideoGrabberName(std::string name, std::string description); + VideoGrabberName(std::string name, std::string description); - std::string getName() const; + std::string getName() const; - std::string getDescription() const; + std::string getDescription() const; - int operator==( const VideoGrabberName &dev ) const; + int operator==( const VideoGrabberName &dev ) const; private: - std::string name; - std::string description; + std::string name; + std::string description; }; #endif /* PLUGIN_DSHOW_VIDEOGRABBERNAME_H */ diff --git a/plugins/pluginDirectShow/internals/wince/CPropertyBag.cxx b/plugins/pluginDirectShow/internals/wince/CPropertyBag.cxx index a6b436a..045530d 100755 --- a/plugins/pluginDirectShow/internals/wince/CPropertyBag.cxx +++ b/plugins/pluginDirectShow/internals/wince/CPropertyBag.cxx @@ -16,14 +16,14 @@ #include "internals/wince/CPropertyBag.h" CPropertyBag::CPropertyBag() : _refCount(1), pVar(0) -{ +{ } CPropertyBag::~CPropertyBag() { VAR_LIST *pTemp = pVar; HRESULT hr = S_OK; - + while(pTemp) { VAR_LIST *pDel = pTemp; VariantClear(&pTemp->var); @@ -35,13 +35,13 @@ CPropertyBag::~CPropertyBag() } HRESULT STDMETHODCALLTYPE -CPropertyBag::Read(LPCOLESTR pszPropName, - VARIANT *_pVar, - IErrorLog *pErrorLog) +CPropertyBag::Read(LPCOLESTR pszPropName, + VARIANT *_pVar, + IErrorLog *pErrorLog) { VAR_LIST *pTemp = pVar; HRESULT hr = S_OK; - + while (pTemp) { if (0 == wcscmp(pszPropName, pTemp->pBSTRName)) { hr = VariantCopy(_pVar, &pTemp->var); @@ -54,8 +54,8 @@ CPropertyBag::Read(LPCOLESTR pszPropName, HRESULT STDMETHODCALLTYPE -CPropertyBag::Write(LPCOLESTR pszPropName, - VARIANT *_pVar) +CPropertyBag::Write(LPCOLESTR pszPropName, + VARIANT *_pVar) { HRESULT hr = S_OK; VAR_LIST *pTemp = new VAR_LIST(); @@ -72,37 +72,37 @@ CPropertyBag::Write(LPCOLESTR pszPropName, return VariantCopy(&pTemp->var, _pVar); } -ULONG STDMETHODCALLTYPE -CPropertyBag::AddRef() +ULONG STDMETHODCALLTYPE +CPropertyBag::AddRef() { return InterlockedIncrement((LONG *)&_refCount); } -ULONG STDMETHODCALLTYPE -CPropertyBag::Release() +ULONG STDMETHODCALLTYPE +CPropertyBag::Release() { ASSERT(_refCount != 0xFFFFFFFF); - ULONG ret = InterlockedDecrement((LONG *)&_refCount); - if (!ret) { - delete this; - } + ULONG ret = InterlockedDecrement((LONG *)&_refCount); + if (!ret) { + delete this; + } return ret; } -HRESULT STDMETHODCALLTYPE -CPropertyBag::QueryInterface(REFIID riid, void** ppv) +HRESULT STDMETHODCALLTYPE +CPropertyBag::QueryInterface(REFIID riid, void** ppv) { - if (!ppv) { + if (!ppv) { return E_POINTER; - } - if (riid == IID_IPropertyBag) { + } + if (riid == IID_IPropertyBag) { *ppv = static_cast<IPropertyBag*>(this); - } - else { + } + else { return *ppv = 0, E_NOINTERFACE; - } - - return AddRef(), S_OK; + } + + return AddRef(), S_OK; } #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/internals/wince/CPropertyBag.h b/plugins/pluginDirectShow/internals/wince/CPropertyBag.h index 20ce779..8abb728 100755 --- a/plugins/pluginDirectShow/internals/wince/CPropertyBag.h +++ b/plugins/pluginDirectShow/internals/wince/CPropertyBag.h @@ -4,40 +4,39 @@ #include "plugin_dshow_config.h" -struct VAR_LIST -{ +struct VAR_LIST { VARIANT var; VAR_LIST *pNext; BSTR pBSTRName; }; class CPropertyBag : public IPropertyBag -{ +{ public: CPropertyBag(); ~CPropertyBag(); - + HRESULT STDMETHODCALLTYPE Read( - LPCOLESTR pszPropName, - VARIANT *pVar, + LPCOLESTR pszPropName, + VARIANT *pVar, IErrorLog *pErrorLog - ); - - + ); + + HRESULT STDMETHODCALLTYPE Write( - LPCOLESTR pszPropName, + LPCOLESTR pszPropName, VARIANT *pVar - ); - - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); + ); + + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); private: - ULONG _refCount; - VAR_LIST *pVar; + ULONG _refCount; + VAR_LIST *pVar; }; #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/internals/wince/DSISampleGrabberCB.h b/plugins/pluginDirectShow/internals/wince/DSISampleGrabberCB.h index 89d8909..ec983d7 100755 --- a/plugins/pluginDirectShow/internals/wince/DSISampleGrabberCB.h +++ b/plugins/pluginDirectShow/internals/wince/DSISampleGrabberCB.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014-2015 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -21,9 +21,8 @@ #include "plugin_dshow_config.h" -interface DSISampleGrabberCB -{ - virtual HRESULT STDMETHODCALLTYPE SampleCB(double SampleTime, IMediaSample *pSample) = 0; +interface DSISampleGrabberCB { + virtual HRESULT STDMETHODCALLTYPE SampleCB(double SampleTime, IMediaSample *pSample) = 0; virtual HRESULT STDMETHODCALLTYPE BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) = 0; }; diff --git a/plugins/pluginDirectShow/internals/wince/DSNullFilter.cxx b/plugins/pluginDirectShow/internals/wince/DSNullFilter.cxx index 76d713c..8b43d83 100755 --- a/plugins/pluginDirectShow/internals/wince/DSNullFilter.cxx +++ b/plugins/pluginDirectShow/internals/wince/DSNullFilter.cxx @@ -1,19 +1,19 @@ #if defined(_WIN32_WCE) /* Copyright (C) 2014-2015 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -21,10 +21,10 @@ #include "internals/wince/DSNullFilter.h" // {7F9F08CF-139F-40b2-A283-01C4EC26A452} -TDSHOW_DEFINE_GUID(CLSID_DSNullFilter, -0x7f9f08cf, 0x139f, 0x40b2, 0xa2, 0x83, 0x1, 0xc4, 0xec, 0x26, 0xa4, 0x52); +TDSHOW_DEFINE_GUID(CLSID_DSNullFilter, + 0x7f9f08cf, 0x139f, 0x40b2, 0xa2, 0x83, 0x1, 0xc4, 0xec, 0x26, 0xa4, 0x52); -DSNullFilter::DSNullFilter(LPUNKNOWN punk,HRESULT *phr) +DSNullFilter::DSNullFilter(LPUNKNOWN punk,HRESULT *phr) : CTransInPlaceFilter(TEXT("NullRenderer"), punk, CLSID_DSNullFilter, phr) { } diff --git a/plugins/pluginDirectShow/internals/wince/DSNullFilter.h b/plugins/pluginDirectShow/internals/wince/DSNullFilter.h index fc9b76a..608a2b6 100755 --- a/plugins/pluginDirectShow/internals/wince/DSNullFilter.h +++ b/plugins/pluginDirectShow/internals/wince/DSNullFilter.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014-2015 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ diff --git a/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.cxx b/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.cxx index d33d105..920111f 100755 --- a/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.cxx +++ b/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.cxx @@ -6,192 +6,191 @@ // {38589364-71FD-4641-B426-E443DB023568} -TDSHOW_DEFINE_GUID(CLSID_SampleGrabber, -0x38589364, 0x71fd, 0x4641, 0xb4, 0x26, 0xe4, 0x43, 0xdb, 0x2, 0x35, 0x68); +TDSHOW_DEFINE_GUID(CLSID_SampleGrabber, + 0x38589364, 0x71fd, 0x4641, 0xb4, 0x26, 0xe4, 0x43, 0xdb, 0x2, 0x35, 0x68); #define RGB565_MASK_RED 0xF800 #define RGB565_MASK_GREEN 0x07E0 #define RGB565_MASK_BLUE 0x001F -DSSampleGrabber::DSSampleGrabber(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) -:CTransInPlaceFilter (tszName, punk, CLSID_SampleGrabber, phr) -{ +DSSampleGrabber::DSSampleGrabber(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) + :CTransInPlaceFilter (tszName, punk, CLSID_SampleGrabber, phr) +{ #define FPS_INPUT 30 #define FPS_OUTPUT 5 - this->m_rtFrameLength = (10000000)/FPS_OUTPUT; + this->m_rtFrameLength = (10000000)/FPS_OUTPUT; - this->m_inputFps = FPS_INPUT; - this->m_outputFps = FPS_OUTPUT; + this->m_inputFps = FPS_INPUT; + this->m_outputFps = FPS_OUTPUT; - this->m_iFrameNumber = 0; - this->m_progress = 0; - this->m_bProcessFrame = true; + this->m_iFrameNumber = 0; + this->m_progress = 0; + this->m_bProcessFrame = true; - this->callback = NULL; - this->m_rgb24 = NULL; + this->callback = NULL; + this->m_rgb24 = NULL; - m_cRef = 0; + m_cRef = 0; } -DSSampleGrabber::~DSSampleGrabber() { - this->callback = NULL; - if(this->m_rgb24) - { - delete[]this->m_rgb24; - this->m_rgb24 = NULL; - } +DSSampleGrabber::~DSSampleGrabber() +{ + this->callback = NULL; + if(this->m_rgb24) { + delete[]this->m_rgb24; + this->m_rgb24 = NULL; + } } HRESULT DSSampleGrabber::SetFps(int inputFps, int outputFps) { - if (inputFps <= 0 || outputFps <= 0) { - return E_FAIL; - } - - // Stop prcessing - this->m_bProcessFrame = false; - - if (inputFps < outputFps) { - this->m_inputFps = this->m_outputFps = inputFps; - } - else { - this->m_outputFps = outputFps; - this->m_inputFps = inputFps; - } - - // Restart processing - this->m_iFrameNumber = 0; - this->m_progress = 0; - this->m_bProcessFrame = true; - - return S_OK; + if (inputFps <= 0 || outputFps <= 0) { + return E_FAIL; + } + + // Stop prcessing + this->m_bProcessFrame = false; + + if (inputFps < outputFps) { + this->m_inputFps = this->m_outputFps = inputFps; + } + else { + this->m_outputFps = outputFps; + this->m_inputFps = inputFps; + } + + // Restart processing + this->m_iFrameNumber = 0; + this->m_progress = 0; + this->m_bProcessFrame = true; + + return S_OK; } HRESULT DSSampleGrabber::Transform(IMediaSample *pSample) -{ - BYTE *pData = NULL; - HRESULT hr = S_OK; - HRESULT ret = S_FALSE; - - if (!this->m_bProcessFrame) { - return S_FALSE; - } - - // Get pointer to the video buffer data - if ( FAILED(pSample->GetPointer(&pData)) ) { - ret = E_FAIL; - goto bail; - } - - pSample->SetTime(NULL, NULL); - - // Drop frame? - if (this->m_iFrameNumber == 0) { - ret = S_OK; - } - else if (this->m_progress >= this->m_inputFps) { - this->m_progress -= this->m_inputFps; - ret = S_OK; - } - - // Mark frame as accepted - if (ret == S_OK) { - // Set TRUE on every sample for uncompressed frames - pSample->SetSyncPoint(TRUE); - - long Size = pSample->GetSize(); - if ( this->callback ) { - LONGLONG start, end; - WORD *rgb565 = (WORD*)pData; - - for(int i = 0, i24 = 0, i565 = 0; i< (Size/2); i++, i24+=3, i565+=1) { - BYTE *p24 = (this->m_rgb24+i24); - WORD val565 = *(rgb565 + i565); - - // extract RGB - p24[2] = (val565 & RGB565_MASK_RED) >> 11; - p24[1] = (val565 & RGB565_MASK_GREEN) >> 5; - p24[0] = (val565 & RGB565_MASK_BLUE); - - // amplify the image - p24[2] <<= 3; - p24[1] <<= 2; - p24[0] <<= 3; - } - - pSample->GetMediaTime(&start, &end); - this->callback->BufferCB( (double)start, this->m_rgb24, ((Size >> 1) * 3)); - } - } - - this->m_progress += this->m_outputFps; - this->m_iFrameNumber++; +{ + BYTE *pData = NULL; + HRESULT hr = S_OK; + HRESULT ret = S_FALSE; + + if (!this->m_bProcessFrame) { + return S_FALSE; + } + + // Get pointer to the video buffer data + if ( FAILED(pSample->GetPointer(&pData)) ) { + ret = E_FAIL; + goto bail; + } + + pSample->SetTime(NULL, NULL); + + // Drop frame? + if (this->m_iFrameNumber == 0) { + ret = S_OK; + } + else if (this->m_progress >= this->m_inputFps) { + this->m_progress -= this->m_inputFps; + ret = S_OK; + } + + // Mark frame as accepted + if (ret == S_OK) { + // Set TRUE on every sample for uncompressed frames + pSample->SetSyncPoint(TRUE); + + long Size = pSample->GetSize(); + if ( this->callback ) { + LONGLONG start, end; + WORD *rgb565 = (WORD*)pData; + + for(int i = 0, i24 = 0, i565 = 0; i< (Size/2); i++, i24+=3, i565+=1) { + BYTE *p24 = (this->m_rgb24+i24); + WORD val565 = *(rgb565 + i565); + + // extract RGB + p24[2] = (val565 & RGB565_MASK_RED) >> 11; + p24[1] = (val565 & RGB565_MASK_GREEN) >> 5; + p24[0] = (val565 & RGB565_MASK_BLUE); + + // amplify the image + p24[2] <<= 3; + p24[1] <<= 2; + p24[0] <<= 3; + } + + pSample->GetMediaTime(&start, &end); + this->callback->BufferCB( (double)start, this->m_rgb24, ((Size >> 1) * 3)); + } + } + + this->m_progress += this->m_outputFps; + this->m_iFrameNumber++; bail: - SAFE_DELETE_ARRAY( pData ); - SAFE_RELEASE(pSample); + SAFE_DELETE_ARRAY( pData ); + SAFE_RELEASE(pSample); - return ret; + return ret; } HRESULT DSSampleGrabber::CheckInputType(const CMediaType* mtIn) -{ - VIDEOINFO *video; - if ( !IsEqualGUID( *mtIn->Subtype(), MEDIASUBTYPE_RGB565 ) || !(video=(VIDEOINFO *)mtIn->Format()) ) { - return E_FAIL; - } +{ + VIDEOINFO *video; + if ( !IsEqualGUID( *mtIn->Subtype(), MEDIASUBTYPE_RGB565 ) || !(video=(VIDEOINFO *)mtIn->Format()) ) { + return E_FAIL; + } - return S_OK; + return S_OK; } -STDMETHODIMP DSSampleGrabber::SetCallback( DSISampleGrabberCB* callback_ ) +STDMETHODIMP DSSampleGrabber::SetCallback( DSISampleGrabberCB* callback_ ) { - if (!callback_) { - return E_FAIL; - } + if (!callback_) { + return E_FAIL; + } - this->callback = callback_; - return S_OK; + this->callback = callback_; + return S_OK; } HRESULT DSSampleGrabber::SetSize(int width, int height) { - ZeroMemory(&this->mt, sizeof(CMediaType)); - - VIDEOINFO *pvi = (VIDEOINFO *)this->mt.AllocFormatBuffer(sizeof(VIDEOINFO)); - if (NULL == pvi) - { - return E_OUTOFMEMORY; - } - - ZeroMemory(pvi, sizeof(VIDEOINFO)); - - pvi->bmiHeader.biCompression = BI_RGB; - pvi->bmiHeader.biBitCount = 24; - pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pvi->bmiHeader.biWidth = width; - pvi->bmiHeader.biHeight = height; - pvi->bmiHeader.biPlanes = 1; - pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); - pvi->bmiHeader.biClrImportant = 0; - - // Frame rate - pvi->AvgTimePerFrame = 10000000/this->m_outputFps; - - SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. - SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle - - this->mt.SetType(&MEDIATYPE_Video); - this->mt.SetFormatType(&FORMAT_VideoInfo); - this->mt.SetTemporalCompression(FALSE); - - this->mt.SetSubtype(&MEDIASUBTYPE_RGB24); - this->mt.SetSampleSize(pvi->bmiHeader.biSizeImage); - - this->m_rgb24 = new BYTE[pvi->bmiHeader.biSizeImage]; - - return S_OK; + ZeroMemory(&this->mt, sizeof(CMediaType)); + + VIDEOINFO *pvi = (VIDEOINFO *)this->mt.AllocFormatBuffer(sizeof(VIDEOINFO)); + if (NULL == pvi) { + return E_OUTOFMEMORY; + } + + ZeroMemory(pvi, sizeof(VIDEOINFO)); + + pvi->bmiHeader.biCompression = BI_RGB; + pvi->bmiHeader.biBitCount = 24; + pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pvi->bmiHeader.biWidth = width; + pvi->bmiHeader.biHeight = height; + pvi->bmiHeader.biPlanes = 1; + pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); + pvi->bmiHeader.biClrImportant = 0; + + // Frame rate + pvi->AvgTimePerFrame = 10000000/this->m_outputFps; + + SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. + SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle + + this->mt.SetType(&MEDIATYPE_Video); + this->mt.SetFormatType(&FORMAT_VideoInfo); + this->mt.SetTemporalCompression(FALSE); + + this->mt.SetSubtype(&MEDIASUBTYPE_RGB24); + this->mt.SetSampleSize(pvi->bmiHeader.biSizeImage); + + this->m_rgb24 = new BYTE[pvi->bmiHeader.biSizeImage]; + + return S_OK; } #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.h b/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.h index 39ee5c6..9ae11cd 100755 --- a/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.h +++ b/plugins/pluginDirectShow/internals/wince/DSSampleGrabber.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014-2015 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -32,42 +32,44 @@ class DSSampleGrabber : public CTransInPlaceFilter { public: - // instantiation - DSSampleGrabber( TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr ); - ~DSSampleGrabber(void); - + // instantiation + DSSampleGrabber( TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr ); + ~DSSampleGrabber(void); + public: - HRESULT Transform(IMediaSample *pSample); + HRESULT Transform(IMediaSample *pSample); HRESULT CheckInputType(const CMediaType* mtIn); - - HRESULT SetFps(int inputFps, int outputFps); + + HRESULT SetFps(int inputFps, int outputFps); // DECLARE_IUNKNOWN; - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { - return GetOwner()->QueryInterface(riid,ppv); - }; - STDMETHODIMP_(ULONG) AddRef() { - return InterlockedIncrement(&m_cRef); - }; + STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { + return GetOwner()->QueryInterface(riid,ppv); + }; + STDMETHODIMP_(ULONG) AddRef() { + return InterlockedIncrement(&m_cRef); + }; STDMETHODIMP_(ULONG) Release() { - return GetOwner()->Release(); + return GetOwner()->Release(); }; - STDMETHODIMP SetCallback(DSISampleGrabberCB* callback_); - HRESULT SetSize(int width, int height); + STDMETHODIMP SetCallback(DSISampleGrabberCB* callback_); + HRESULT SetSize(int width, int height); - inline AM_MEDIA_TYPE GetMediaType() { return (AM_MEDIA_TYPE)this->mt; } + inline AM_MEDIA_TYPE GetMediaType() { + return (AM_MEDIA_TYPE)this->mt; + } private: - int m_progress; - int m_inputFps, m_outputFps; - bool m_bProcessFrame; - REFERENCE_TIME m_rtFrameLength; // UNITS/fps - LONGLONG m_iFrameNumber; + int m_progress; + int m_inputFps, m_outputFps; + bool m_bProcessFrame; + REFERENCE_TIME m_rtFrameLength; // UNITS/fps + LONGLONG m_iFrameNumber; - DSISampleGrabberCB* callback; - CMediaType mt; - BYTE *m_rgb24; + DSISampleGrabberCB* callback; + CMediaType mt; + BYTE *m_rgb24; }; #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/internals/wince/DSSampleGrabberUtils.h b/plugins/pluginDirectShow/internals/wince/DSSampleGrabberUtils.h index 01e1728..e22be83 100755 --- a/plugins/pluginDirectShow/internals/wince/DSSampleGrabberUtils.h +++ b/plugins/pluginDirectShow/internals/wince/DSSampleGrabberUtils.h @@ -1,17 +1,17 @@ /* Copyright (C) 2014-2015 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -25,14 +25,16 @@ typedef void (CALLBACK *MANAGEDCALLBACKPROC)(BYTE* pdata, long len); // ISampleGrabber interface definition // {04951BFF-696A-4ade-828D-42A5F1EDB631} -DEFINE_GUID(IID_ISampleGrabber, - 0x4951bff, 0x696a, 0x4ade, 0x82, 0x8d, 0x42, 0xa5, 0xf1, 0xed, 0xb6, 0x31); +DEFINE_GUID(IID_ISampleGrabber, + 0x4951bff, 0x696a, 0x4ade, 0x82, 0x8d, 0x42, 0xa5, 0xf1, 0xed, 0xb6, 0x31); -DECLARE_INTERFACE_(ISampleGrabber, IUnknown) { - STDMETHOD(SetCallback)(MANAGEDCALLBACKPROC callback) PURE;}; +DECLARE_INTERFACE_(ISampleGrabber, IUnknown) +{ + STDMETHOD(SetCallback)(MANAGEDCALLBACKPROC callback) PURE; +}; - // {D11DFE19-8864-4a60-B26C-552F9AA472E1} +// {D11DFE19-8864-4a60-B26C-552F9AA472E1} DEFINE_GUID(CLSID_NullRenderer, - 0xd11dfe19, 0x8864, 0x4a60, 0xb2, 0x6c, 0x55, 0x2f, 0x9a, 0xa4, 0x72, 0xe1); + 0xd11dfe19, 0x8864, 0x4a60, 0xb2, 0x6c, 0x55, 0x2f, 0x9a, 0xa4, 0x72, 0xe1); #endif /* _WIN32_WCE */ diff --git a/plugins/pluginDirectShow/plugin_dshow_config.h b/plugins/pluginDirectShow/plugin_dshow_config.h index f58e4b2..df01cda 100755 --- a/plugins/pluginDirectShow/plugin_dshow_config.h +++ b/plugins/pluginDirectShow/plugin_dshow_config.h @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -42,13 +42,13 @@ # define PLUGIN_DSHOW_GEXTERN extern #endif -/* Guards against C++ name mangling +/* Guards against C++ name mangling */ #ifdef __cplusplus # define PLUGIN_DSHOW_BEGIN_DECLS extern "C" { # define PLUGIN_DSHOW_END_DECLS } #else -# define PLUGIN_DSHOW_BEGIN_DECLS +# define PLUGIN_DSHOW_BEGIN_DECLS # define PLUGIN_DSHOW_END_DECLS #endif @@ -79,7 +79,7 @@ #endif #if HAVE_CONFIG_H - #include <config.h> +#include <config.h> #endif #if !defined(TDSHOW_DEFINE_GUID) && !defined(_WIN32_WCE) diff --git a/plugins/pluginDirectShow/plugin_screencast_dshow_producer.cxx b/plugins/pluginDirectShow/plugin_screencast_dshow_producer.cxx index af09c4e..789c7b9 100755 --- a/plugins/pluginDirectShow/plugin_screencast_dshow_producer.cxx +++ b/plugins/pluginDirectShow/plugin_screencast_dshow_producer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2014 Mamadou DIOP -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,181 +26,184 @@ #define DSPRODUCER(self) ((plugin_screencast_dshow_producer_t*)(self)) -typedef struct plugin_screencast_dshow_producer_s -{ - TMEDIA_DECLARE_PRODUCER; - - DSGrabber* grabber; - INT64 previewHwnd; - - tsk_bool_t started; - tsk_bool_t mute; - tsk_bool_t create_on_ui_thread; +typedef struct plugin_screencast_dshow_producer_s { + TMEDIA_DECLARE_PRODUCER; + + DSGrabber* grabber; + INT64 previewHwnd; + + tsk_bool_t started; + tsk_bool_t mute; + tsk_bool_t create_on_ui_thread; } plugin_screencast_dshow_producer_t; // Producer callback (From DirectShow Grabber to our plugin) static int plugin_video_dshow_plugin_cb(const void* callback_data, const void* buffer, tsk_size_t size) { - const plugin_screencast_dshow_producer_t* producer = (const plugin_screencast_dshow_producer_t*)callback_data; + const plugin_screencast_dshow_producer_t* producer = (const plugin_screencast_dshow_producer_t*)callback_data; - if (producer && TMEDIA_PRODUCER(producer)->enc_cb.callback) { - TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, buffer, size); - } + if (producer && TMEDIA_PRODUCER(producer)->enc_cb.callback) { + TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, buffer, size); + } - return 0; + return 0; } /* ============ Media Producer Interface ================= */ static int plugin_screencast_dshow_producer_set(tmedia_producer_t *self, const tmedia_param_t* param) { - int ret = 0; - plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; - - if(!producer || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(param->value_type == tmedia_pvt_int64){ - if(tsk_striequals(param->key, "local-hwnd")){ - DSPRODUCER(producer)->previewHwnd = (INT64)*((int64_t*)param->value); - if(DSPRODUCER(producer)->grabber && DSPRODUCER(self)->grabber->preview){ - DSPRODUCER(producer)->grabber->preview->attach(DSPRODUCER(producer)->previewHwnd); - } - } - } - else if(param->value_type == tmedia_pvt_int32){ - if(tsk_striequals(param->key, "mute")){ - producer->mute = (TSK_TO_INT32((uint8_t*)param->value) != 0); - if(producer->started){ - if(producer->mute){ - producer->grabber->pause(); - } - else{ - producer->grabber->start(); - } - } - } - else if(tsk_striequals(param->key, "create-on-current-thead")){ - producer->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; - } - else if(tsk_striequals(param->key, "plugin-firefox")){ - TSK_DEBUG_INFO("'plugin-firefox' ignored for screencast"); - } - } - - return ret; + int ret = 0; + plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; + + if(!producer || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(param->value_type == tmedia_pvt_int64) { + if(tsk_striequals(param->key, "local-hwnd")) { + DSPRODUCER(producer)->previewHwnd = (INT64)*((int64_t*)param->value); + if(DSPRODUCER(producer)->grabber && DSPRODUCER(self)->grabber->preview) { + DSPRODUCER(producer)->grabber->preview->attach(DSPRODUCER(producer)->previewHwnd); + } + } + } + else if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "mute")) { + producer->mute = (TSK_TO_INT32((uint8_t*)param->value) != 0); + if(producer->started) { + if(producer->mute) { + producer->grabber->pause(); + } + else { + producer->grabber->start(); + } + } + } + else if(tsk_striequals(param->key, "create-on-current-thead")) { + producer->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; + } + else if(tsk_striequals(param->key, "plugin-firefox")) { + TSK_DEBUG_INFO("'plugin-firefox' ignored for screencast"); + } + } + + return ret; } static int plugin_screencast_dshow_producer_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec) { - plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; - - if(!producer || !codec && codec->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - TMEDIA_PRODUCER(producer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->out.fps; - TMEDIA_PRODUCER(producer)->video.width = TMEDIA_CODEC_VIDEO(codec)->out.width; - TMEDIA_PRODUCER(producer)->video.height = TMEDIA_CODEC_VIDEO(codec)->out.height; - - return 0; + plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; + + if(!producer || !codec && codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + TMEDIA_PRODUCER(producer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->out.fps; + TMEDIA_PRODUCER(producer)->video.width = TMEDIA_CODEC_VIDEO(codec)->out.width; + TMEDIA_PRODUCER(producer)->video.height = TMEDIA_CODEC_VIDEO(codec)->out.height; + + return 0; } static int plugin_screencast_dshow_producer_start(tmedia_producer_t* self) { - plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; - HRESULT hr = S_OK; - - if (!producer) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (producer->started) { - return 0; - } - - // create grabber on ALWAYS current thread - if (!producer->grabber) { - static BOOL __isDisplayFalse = FALSE; - static BOOL __isScreenCastTrue = TRUE; - if(producer->create_on_ui_thread) createOnUIThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue); - else createOnCurrentThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue); - if (!producer->grabber) { - TSK_DEBUG_ERROR("Failed to create grabber"); - return -2; - } - } - - // set parameters - producer->grabber->setCaptureParameters((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height, TMEDIA_PRODUCER(producer)->video.fps); - - // set callback function - producer->grabber->setCallback(plugin_video_dshow_plugin_cb, producer); - - // attach preview - if (producer->grabber->preview) { - if (producer->previewHwnd) { - producer->grabber->preview->attach(producer->previewHwnd); - } - producer->grabber->preview->setSize((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height); - } - - // start grabber - if (!producer->mute) { - producer->grabber->start(); - } - - producer->started = tsk_true; - - return 0; + plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; + HRESULT hr = S_OK; + + if (!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (producer->started) { + return 0; + } + + // create grabber on ALWAYS current thread + if (!producer->grabber) { + static BOOL __isDisplayFalse = FALSE; + static BOOL __isScreenCastTrue = TRUE; + if(producer->create_on_ui_thread) { + createOnUIThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue); + } + else { + createOnCurrentThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastTrue); + } + if (!producer->grabber) { + TSK_DEBUG_ERROR("Failed to create grabber"); + return -2; + } + } + + // set parameters + producer->grabber->setCaptureParameters((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height, TMEDIA_PRODUCER(producer)->video.fps); + + // set callback function + producer->grabber->setCallback(plugin_video_dshow_plugin_cb, producer); + + // attach preview + if (producer->grabber->preview) { + if (producer->previewHwnd) { + producer->grabber->preview->attach(producer->previewHwnd); + } + producer->grabber->preview->setSize((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height); + } + + // start grabber + if (!producer->mute) { + producer->grabber->start(); + } + + producer->started = tsk_true; + + return 0; } static int plugin_screencast_dshow_producer_pause(tmedia_producer_t* self) { - plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; + plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!producer->grabber){ - TSK_DEBUG_ERROR("Invalid internal grabber"); - return -2; - } + if(!producer->grabber) { + TSK_DEBUG_ERROR("Invalid internal grabber"); + return -2; + } - producer->grabber->pause(); + producer->grabber->pause(); - return 0; + return 0; } static int plugin_screencast_dshow_producer_stop(tmedia_producer_t* self) { - plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; + plugin_screencast_dshow_producer_t* producer = (plugin_screencast_dshow_producer_t*)self; - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!producer->started){ - return 0; - } + if(!producer->started) { + return 0; + } - if(!producer->grabber){ - TSK_DEBUG_ERROR("Invalid internal grabber"); - return -2; - } + if(!producer->grabber) { + TSK_DEBUG_ERROR("Invalid internal grabber"); + return -2; + } - producer->grabber->stop(); - producer->started = tsk_false; + producer->grabber->stop(); + producer->started = tsk_false; - return 0; + return 0; } @@ -210,64 +213,62 @@ static int plugin_screencast_dshow_producer_stop(tmedia_producer_t* self) /* constructor */ static tsk_object_t* plugin_screencast_dshow_producer_ctor(tsk_object_t * self, va_list * app) { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self; - if(producer){ - /* init base */ - tmedia_producer_init(TMEDIA_PRODUCER(producer)); - TMEDIA_PRODUCER(producer)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 - /* init self with default values*/ - producer->create_on_ui_thread = tsk_true; - TMEDIA_PRODUCER(producer)->video.fps = 15; - TMEDIA_PRODUCER(producer)->video.width = 352; - TMEDIA_PRODUCER(producer)->video.height = 288; - } - return self; + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self; + if(producer) { + /* init base */ + tmedia_producer_init(TMEDIA_PRODUCER(producer)); + TMEDIA_PRODUCER(producer)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 + /* init self with default values*/ + producer->create_on_ui_thread = tsk_true; + TMEDIA_PRODUCER(producer)->video.fps = 15; + TMEDIA_PRODUCER(producer)->video.width = 352; + TMEDIA_PRODUCER(producer)->video.height = 288; + } + return self; } /* destructor */ static tsk_object_t* plugin_screencast_dshow_producer_dtor(tsk_object_t * self) -{ - plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self; - if(producer){ - /* stop */ - if(producer->started){ - plugin_screencast_dshow_producer_stop((tmedia_producer_t*)self); - } - - /* for safety */ - if(producer->grabber){ - producer->grabber->setCallback(tsk_null, tsk_null); - } - - /* deinit base */ - tmedia_producer_deinit(TMEDIA_PRODUCER(producer)); - /* deinit self */ - SAFE_DELETE_PTR(producer->grabber); - } - - return self; +{ + plugin_screencast_dshow_producer_t *producer = (plugin_screencast_dshow_producer_t *)self; + if(producer) { + /* stop */ + if(producer->started) { + plugin_screencast_dshow_producer_stop((tmedia_producer_t*)self); + } + + /* for safety */ + if(producer->grabber) { + producer->grabber->setCallback(tsk_null, tsk_null); + } + + /* deinit base */ + tmedia_producer_deinit(TMEDIA_PRODUCER(producer)); + /* deinit self */ + SAFE_DELETE_PTR(producer->grabber); + } + + return self; } /* object definition */ -static const tsk_object_def_t plugin_screencast_dshow_producer_def_s = -{ - sizeof(plugin_screencast_dshow_producer_t), - plugin_screencast_dshow_producer_ctor, - plugin_screencast_dshow_producer_dtor, - tsk_null, +static const tsk_object_def_t plugin_screencast_dshow_producer_def_s = { + sizeof(plugin_screencast_dshow_producer_t), + plugin_screencast_dshow_producer_ctor, + plugin_screencast_dshow_producer_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_producer_plugin_def_t plugin_screencast_dshow_producer_plugin_def_s = -{ - &plugin_screencast_dshow_producer_def_s, - - tmedia_bfcp_video, - "Microsoft DirectShow producer (ScrenCast)", - - plugin_screencast_dshow_producer_set, - plugin_screencast_dshow_producer_prepare, - plugin_screencast_dshow_producer_start, - plugin_screencast_dshow_producer_pause, - plugin_screencast_dshow_producer_stop +static const tmedia_producer_plugin_def_t plugin_screencast_dshow_producer_plugin_def_s = { + &plugin_screencast_dshow_producer_def_s, + + tmedia_bfcp_video, + "Microsoft DirectShow producer (ScrenCast)", + + plugin_screencast_dshow_producer_set, + plugin_screencast_dshow_producer_prepare, + plugin_screencast_dshow_producer_start, + plugin_screencast_dshow_producer_pause, + plugin_screencast_dshow_producer_stop }; const tmedia_producer_plugin_def_t *plugin_screencast_dshow_producer_plugin_def_t = &plugin_screencast_dshow_producer_plugin_def_s; diff --git a/plugins/pluginDirectShow/plugin_video_dshow_consumer.cxx b/plugins/pluginDirectShow/plugin_video_dshow_consumer.cxx index dfd7e72..3d47f4c 100755 --- a/plugins/pluginDirectShow/plugin_video_dshow_consumer.cxx +++ b/plugins/pluginDirectShow/plugin_video_dshow_consumer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -55,33 +55,32 @@ const DWORD NUM_BACK_BUFFERS = 2; (*ppT)->Release(); \ *ppT = NULL; \ } \ -} +} #undef CHECK_HR // In CHECK_HR(x) When (x) is a function it will be executed twice when used in "TSK_DEBUG_ERROR(x)" and "If(x)" #define CHECK_HR(x) { HRESULT __hr__ = (x); if (FAILED(__hr__)) { TSK_DEBUG_ERROR("Operation Failed (%08x)", __hr__); goto bail; } } -typedef struct _DSRatio - { +typedef struct _DSRatio { DWORD Numerator; DWORD Denominator; - } DSRatio; +} DSRatio; static HRESULT CreateDeviceD3D9( - HWND hWnd, - IDirect3DDevice9** ppDevice, - IDirect3D9 **ppD3D, - D3DPRESENT_PARAMETERS &d3dpp - ); + HWND hWnd, + IDirect3DDevice9** ppDevice, + IDirect3D9 **ppD3D, + D3DPRESENT_PARAMETERS &d3dpp +); static HRESULT TestCooperativeLevel( - struct plugin_video_dshow_consumer_s *pSelf - ); + struct plugin_video_dshow_consumer_s *pSelf +); static HRESULT CreateSwapChain( - HWND hWnd, - UINT32 nFrameWidth, - UINT32 nFrameHeight, - IDirect3DDevice9* pDevice, - IDirect3DSwapChain9 **ppSwapChain); + HWND hWnd, + UINT32 nFrameWidth, + UINT32 nFrameHeight, + IDirect3DDevice9* pDevice, + IDirect3DSwapChain9 **ppSwapChain); static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -98,30 +97,29 @@ static HRESULT HookWindow(struct plugin_video_dshow_consumer_s *pSelf, HWND hWnd static HRESULT UnhookWindow(struct plugin_video_dshow_consumer_s *pSelf); -typedef struct plugin_video_dshow_consumer_s -{ - TMEDIA_DECLARE_CONSUMER; - - BOOL bStarted, bPrepared, bPaused, bFullScreen, bWindowHooked; - BOOL bPluginFireFox, bPluginWebRTC4All; - HWND hWindow; - WNDPROC wndProc; - HWND hWindowFullScreen; - RECT rcWindow; - RECT rcDest; - DSRatio pixelAR; - - UINT32 nNegWidth; - UINT32 nNegHeight; - UINT32 nNegFps; - - D3DLOCKED_RECT rcLock; - IDirect3DDevice9* pDevice; - IDirect3D9 *pD3D; - IDirect3DSwapChain9 *pSwapChain; - D3DPRESENT_PARAMETERS d3dpp; - - TSK_DECLARE_SAFEOBJ; +typedef struct plugin_video_dshow_consumer_s { + TMEDIA_DECLARE_CONSUMER; + + BOOL bStarted, bPrepared, bPaused, bFullScreen, bWindowHooked; + BOOL bPluginFireFox, bPluginWebRTC4All; + HWND hWindow; + WNDPROC wndProc; + HWND hWindowFullScreen; + RECT rcWindow; + RECT rcDest; + DSRatio pixelAR; + + UINT32 nNegWidth; + UINT32 nNegHeight; + UINT32 nNegFps; + + D3DLOCKED_RECT rcLock; + IDirect3DDevice9* pDevice; + IDirect3D9 *pD3D; + IDirect3DSwapChain9 *pSwapChain; + D3DPRESENT_PARAMETERS d3dpp; + + TSK_DECLARE_SAFEOBJ; } plugin_video_dshow_consumer_t; @@ -130,377 +128,345 @@ static int _plugin_video_dshow_consumer_unprepare(plugin_video_dshow_consumer_t* /* ============ Media Consumer Interface ================= */ static int plugin_video_dshow_consumer_set(tmedia_consumer_t *self, const tmedia_param_t* param) { - int ret = 0; - HRESULT hr = S_OK; - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - - if(!self || !param) - { - TSK_DEBUG_ERROR("Invalid parameter"); - CHECK_HR(hr = E_POINTER); - } - - if(param->value_type == tmedia_pvt_int64) - { - if(tsk_striequals(param->key, "remote-hwnd")) - { - HWND hWnd = reinterpret_cast<HWND>((INT64)*((int64_t*)param->value)); - if(hWnd != pSelf->hWindow) - { - tsk_safeobj_lock(pSelf); // block consumer thread - pSelf->hWindow = hWnd; - if(pSelf->bPrepared) - { - hr = ResetDevice(pSelf); - } - tsk_safeobj_unlock(pSelf); // unblock consumer thread - } - } - } - else if(param->value_type == tmedia_pvt_int32) - { - if(tsk_striequals(param->key, "fullscreen")) - { - BOOL bFullScreen = !!*((int32_t*)param->value); - TSK_DEBUG_INFO("[MF video consumer] Full Screen = %d", bFullScreen); - CHECK_HR(hr = SetFullscreen(pSelf, bFullScreen)); - } - else if(tsk_striequals(param->key, "create-on-current-thead")) - { - // DSCONSUMER(self)->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; - } - else if(tsk_striequals(param->key, "plugin-firefox")) - { - pSelf->bPluginFireFox = (*((int32_t*)param->value) != 0); - } - else if(tsk_striequals(param->key, "plugin-webrtc4all")) - { - pSelf->bPluginWebRTC4All = (*((int32_t*)param->value) != 0); - } - } - - CHECK_HR(hr); + int ret = 0; + HRESULT hr = S_OK; + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + + if(!self || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + CHECK_HR(hr = E_POINTER); + } + + if(param->value_type == tmedia_pvt_int64) { + if(tsk_striequals(param->key, "remote-hwnd")) { + HWND hWnd = reinterpret_cast<HWND>((INT64)*((int64_t*)param->value)); + if(hWnd != pSelf->hWindow) { + tsk_safeobj_lock(pSelf); // block consumer thread + pSelf->hWindow = hWnd; + if(pSelf->bPrepared) { + hr = ResetDevice(pSelf); + } + tsk_safeobj_unlock(pSelf); // unblock consumer thread + } + } + } + else if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "fullscreen")) { + BOOL bFullScreen = !!*((int32_t*)param->value); + TSK_DEBUG_INFO("[MF video consumer] Full Screen = %d", bFullScreen); + CHECK_HR(hr = SetFullscreen(pSelf, bFullScreen)); + } + else if(tsk_striequals(param->key, "create-on-current-thead")) { + // DSCONSUMER(self)->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; + } + else if(tsk_striequals(param->key, "plugin-firefox")) { + pSelf->bPluginFireFox = (*((int32_t*)param->value) != 0); + } + else if(tsk_striequals(param->key, "plugin-webrtc4all")) { + pSelf->bPluginWebRTC4All = (*((int32_t*)param->value) != 0); + } + } + + CHECK_HR(hr); bail: - return SUCCEEDED(hr) ? 0 : -1; + return SUCCEEDED(hr) ? 0 : -1; } static int plugin_video_dshow_consumer_prepare(tmedia_consumer_t* self, const tmedia_codec_t* codec) { - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - - if(!pSelf || !codec && codec->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(pSelf->bPrepared){ - TSK_DEBUG_WARN("D3D9 video consumer already prepared"); - return -1; - } - - HRESULT hr = S_OK; - HWND hWnd = Window(pSelf); - - TMEDIA_CONSUMER(pSelf)->video.fps = TMEDIA_CODEC_VIDEO(codec)->in.fps; - TMEDIA_CONSUMER(pSelf)->video.in.width = TMEDIA_CODEC_VIDEO(codec)->in.width; - TMEDIA_CONSUMER(pSelf)->video.in.height = TMEDIA_CODEC_VIDEO(codec)->in.height; - - if(!TMEDIA_CONSUMER(pSelf)->video.display.width){ - TMEDIA_CONSUMER(pSelf)->video.display.width = TMEDIA_CONSUMER(pSelf)->video.in.width; - } - if(!TMEDIA_CONSUMER(pSelf)->video.display.height){ - TMEDIA_CONSUMER(pSelf)->video.display.height = TMEDIA_CONSUMER(pSelf)->video.in.height; - } - - pSelf->nNegFps = (UINT32)TMEDIA_CONSUMER(pSelf)->video.fps; - pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.display.width; - pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.display.height; - - TSK_DEBUG_INFO("D3D9 video consumer: fps=%d, width=%d, height=%d", - pSelf->nNegFps, - pSelf->nNegWidth, - pSelf->nNegHeight); - - TMEDIA_CONSUMER(pSelf)->video.display.chroma = tmedia_chroma_rgb32; - TMEDIA_CONSUMER(pSelf)->decoder.codec_id = tmedia_codec_id_none; // means accept RAW fames - - // The window handle is not created until the call is connect (incoming only) - At least on Internet Explorer 10 - if(hWnd && !pSelf->bPluginWebRTC4All) - { - CHECK_HR(hr = CreateDeviceD3D9(hWnd, &pSelf->pDevice, &pSelf->pD3D, pSelf->d3dpp)); - CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); - } - else - { - if(hWnd && pSelf->bPluginWebRTC4All) - { - TSK_DEBUG_INFO("[MF consumer] HWND is defined but we detected webrtc4all...delaying D3D9 device creating until session get connected"); - } - else - { - TSK_DEBUG_WARN("Delaying D3D9 device creation because HWND is not defined yet"); - } - } + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + + if(!pSelf || !codec && codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(pSelf->bPrepared) { + TSK_DEBUG_WARN("D3D9 video consumer already prepared"); + return -1; + } + + HRESULT hr = S_OK; + HWND hWnd = Window(pSelf); + + TMEDIA_CONSUMER(pSelf)->video.fps = TMEDIA_CODEC_VIDEO(codec)->in.fps; + TMEDIA_CONSUMER(pSelf)->video.in.width = TMEDIA_CODEC_VIDEO(codec)->in.width; + TMEDIA_CONSUMER(pSelf)->video.in.height = TMEDIA_CODEC_VIDEO(codec)->in.height; + + if(!TMEDIA_CONSUMER(pSelf)->video.display.width) { + TMEDIA_CONSUMER(pSelf)->video.display.width = TMEDIA_CONSUMER(pSelf)->video.in.width; + } + if(!TMEDIA_CONSUMER(pSelf)->video.display.height) { + TMEDIA_CONSUMER(pSelf)->video.display.height = TMEDIA_CONSUMER(pSelf)->video.in.height; + } + + pSelf->nNegFps = (UINT32)TMEDIA_CONSUMER(pSelf)->video.fps; + pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.display.width; + pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.display.height; + + TSK_DEBUG_INFO("D3D9 video consumer: fps=%d, width=%d, height=%d", + pSelf->nNegFps, + pSelf->nNegWidth, + pSelf->nNegHeight); + + TMEDIA_CONSUMER(pSelf)->video.display.chroma = tmedia_chroma_rgb32; + TMEDIA_CONSUMER(pSelf)->decoder.codec_id = tmedia_codec_id_none; // means accept RAW fames + + // The window handle is not created until the call is connect (incoming only) - At least on Internet Explorer 10 + if(hWnd && !pSelf->bPluginWebRTC4All) { + CHECK_HR(hr = CreateDeviceD3D9(hWnd, &pSelf->pDevice, &pSelf->pD3D, pSelf->d3dpp)); + CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); + } + else { + if(hWnd && pSelf->bPluginWebRTC4All) { + TSK_DEBUG_INFO("[MF consumer] HWND is defined but we detected webrtc4all...delaying D3D9 device creating until session get connected"); + } + else { + TSK_DEBUG_WARN("Delaying D3D9 device creation because HWND is not defined yet"); + } + } bail: - pSelf->bPrepared = SUCCEEDED(hr); - return pSelf->bPrepared ? 0 : -1; + pSelf->bPrepared = SUCCEEDED(hr); + return pSelf->bPrepared ? 0 : -1; } static int plugin_video_dshow_consumer_start(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - if(!pSelf){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pSelf) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(pSelf->bStarted){ - TSK_DEBUG_INFO("D3D9 video consumer already started"); - return 0; - } - if(!pSelf->bPrepared){ - TSK_DEBUG_ERROR("D3D9 video consumer not prepared"); - return -1; - } + if(pSelf->bStarted) { + TSK_DEBUG_INFO("D3D9 video consumer already started"); + return 0; + } + if(!pSelf->bPrepared) { + TSK_DEBUG_ERROR("D3D9 video consumer not prepared"); + return -1; + } - HRESULT hr = S_OK; + HRESULT hr = S_OK; - pSelf->bPaused = false; - pSelf->bStarted = true; + pSelf->bPaused = false; + pSelf->bStarted = true; - return SUCCEEDED(hr) ? 0 : -1; + return SUCCEEDED(hr) ? 0 : -1; } static int plugin_video_dshow_consumer_consume(tmedia_consumer_t* self, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr) { - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - HRESULT hr = S_OK; - HWND hWnd = Window(pSelf); + HRESULT hr = S_OK; + HWND hWnd = Window(pSelf); - IDirect3DSurface9 *pSurf = NULL; + IDirect3DSurface9 *pSurf = NULL; IDirect3DSurface9 *pBB = NULL; - if(!pSelf) - { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; // because of the mutex lock do it here - } - - tsk_safeobj_lock(pSelf); - - if(!buffer || !size) - { - TSK_DEBUG_ERROR("Invalid parameter"); - CHECK_HR(hr = E_INVALIDARG); - } - - if(!pSelf->bStarted) - { - TSK_DEBUG_INFO("D3D9 video consumer not started"); - CHECK_HR(hr = E_FAIL); - } - - if(!hWnd) - { - TSK_DEBUG_INFO("Do not draw frame because HWND not set"); - goto bail; // not an error as the application can decide to set the HWND at any time - } - - if (!pSelf->bWindowHooked) - { - // Do not hook "hWnd" as it could be the fullscreen handle which is always hooked. - CHECK_HR(hr = HookWindow(pSelf, pSelf->hWindow)); - } - - if(!pSelf->pDevice || !pSelf->pD3D || !pSelf->pSwapChain) - { - if(pSelf->pDevice || pSelf->pD3D || pSelf->pSwapChain) - { - CHECK_HR(hr = E_POINTER); // They must be "all null" or "all valid" - } - - if(hWnd) - { - // means HWND was not set but defined now - pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width; - pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height; - - CHECK_HR(hr = CreateDeviceD3D9(hWnd, &pSelf->pDevice, &pSelf->pD3D, pSelf->d3dpp)); - CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); - } - } - - if(pSelf->nNegWidth != TMEDIA_CONSUMER(pSelf)->video.in.width || pSelf->nNegHeight != TMEDIA_CONSUMER(pSelf)->video.in.height){ - TSK_DEBUG_INFO("Negotiated and input video sizes are different:%d#%d or %d#%d", - pSelf->nNegWidth, TMEDIA_CONSUMER(pSelf)->video.in.width, - pSelf->nNegHeight, TMEDIA_CONSUMER(pSelf)->video.in.height); - // Update media type - - SafeRelease(&pSelf->pSwapChain); - CHECK_HR(hr = CreateSwapChain(hWnd, (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width, (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height, pSelf->pDevice, &pSelf->pSwapChain)); - - pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width; - pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height; - - // Update Destination will do noting if the window size haven't changed. - // Force updating the destination rect if negotiated size change - CHECK_HR(hr = UpdateDestinationRect(pSelf, TRUE/* Force */)); - } - - if(((pSelf->nNegWidth * pSelf->nNegHeight) << 2) != size) - { - TSK_DEBUG_ERROR("%u not valid as input size", size); - CHECK_HR(hr = E_FAIL); - } - - CHECK_HR(hr = TestCooperativeLevel(pSelf)); - - CHECK_HR(hr = UpdateDestinationRect(pSelf)); - - CHECK_HR(hr = pSelf->pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf)); - CHECK_HR(hr = pSurf->LockRect(&pSelf->rcLock, NULL, D3DLOCK_NOSYSLOCK )); - - // Fast copy() using MMX, SSE, or SSE2 - // Only available on Vista or later: Use LoadLibrary() to get a pointer to the function - /*hr = MFCopyImage( - (BYTE*)pSelf->rcLock.pBits, - pSelf->rcLock.Pitch, - (BYTE*)buffer, - (pSelf->nNegWidth << 2), - (pSelf->nNegWidth << 2), - pSelf->nNegHeight - );*/ - - if(pSelf->rcLock.Pitch == (pSelf->nNegWidth << 2)) - { - memcpy(pSelf->rcLock.pBits, buffer, size); - } - else - { - const BYTE* pSrcPtr = (const BYTE*)buffer; - BYTE* pDstPtr = (BYTE*)pSelf->rcLock.pBits; - UINT32 nDstPitch = pSelf->rcLock.Pitch; - UINT32 nSrcPitch = (pSelf->nNegWidth << 2); - for(UINT32 i = 0; i < pSelf->nNegHeight; ++i) - { - memcpy(pDstPtr, pSrcPtr, nSrcPitch); - pDstPtr += nDstPitch; - pSrcPtr += nSrcPitch; - } - } - - if(FAILED(hr)) - { - // unlock() before leaving - pSurf->UnlockRect(); - CHECK_HR(hr); - } - - CHECK_HR(hr = pSurf->UnlockRect()); - - // Color fill the back buffer - CHECK_HR(hr = pSelf->pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBB)); - CHECK_HR(hr = pSelf->pDevice->ColorFill(pBB, NULL, D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF))); - - // Resize keeping aspect ratio and Blit the frame (required) - hr = pSelf->pDevice->StretchRect( - pSurf, - NULL, - pBB, - &pSelf->rcDest/*NULL*/, - D3DTEXF_LINEAR - ); // could fail when display is being resized - if(SUCCEEDED(hr)) - { - // Present the frame - CHECK_HR(hr = pSelf->pDevice->Present(NULL, NULL, NULL, NULL)); - } - else - { - TSK_DEBUG_INFO("StretchRect returned ...%x", hr); - } + if(!pSelf) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; // because of the mutex lock do it here + } + + tsk_safeobj_lock(pSelf); + + if(!buffer || !size) { + TSK_DEBUG_ERROR("Invalid parameter"); + CHECK_HR(hr = E_INVALIDARG); + } + + if(!pSelf->bStarted) { + TSK_DEBUG_INFO("D3D9 video consumer not started"); + CHECK_HR(hr = E_FAIL); + } + + if(!hWnd) { + TSK_DEBUG_INFO("Do not draw frame because HWND not set"); + goto bail; // not an error as the application can decide to set the HWND at any time + } + + if (!pSelf->bWindowHooked) { + // Do not hook "hWnd" as it could be the fullscreen handle which is always hooked. + CHECK_HR(hr = HookWindow(pSelf, pSelf->hWindow)); + } + + if(!pSelf->pDevice || !pSelf->pD3D || !pSelf->pSwapChain) { + if(pSelf->pDevice || pSelf->pD3D || pSelf->pSwapChain) { + CHECK_HR(hr = E_POINTER); // They must be "all null" or "all valid" + } + + if(hWnd) { + // means HWND was not set but defined now + pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width; + pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height; + + CHECK_HR(hr = CreateDeviceD3D9(hWnd, &pSelf->pDevice, &pSelf->pD3D, pSelf->d3dpp)); + CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); + } + } + + if(pSelf->nNegWidth != TMEDIA_CONSUMER(pSelf)->video.in.width || pSelf->nNegHeight != TMEDIA_CONSUMER(pSelf)->video.in.height) { + TSK_DEBUG_INFO("Negotiated and input video sizes are different:%d#%d or %d#%d", + pSelf->nNegWidth, TMEDIA_CONSUMER(pSelf)->video.in.width, + pSelf->nNegHeight, TMEDIA_CONSUMER(pSelf)->video.in.height); + // Update media type + + SafeRelease(&pSelf->pSwapChain); + CHECK_HR(hr = CreateSwapChain(hWnd, (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width, (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height, pSelf->pDevice, &pSelf->pSwapChain)); + + pSelf->nNegWidth = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.width; + pSelf->nNegHeight = (UINT32)TMEDIA_CONSUMER(pSelf)->video.in.height; + + // Update Destination will do noting if the window size haven't changed. + // Force updating the destination rect if negotiated size change + CHECK_HR(hr = UpdateDestinationRect(pSelf, TRUE/* Force */)); + } + + if(((pSelf->nNegWidth * pSelf->nNegHeight) << 2) != size) { + TSK_DEBUG_ERROR("%u not valid as input size", size); + CHECK_HR(hr = E_FAIL); + } + + CHECK_HR(hr = TestCooperativeLevel(pSelf)); + + CHECK_HR(hr = UpdateDestinationRect(pSelf)); + + CHECK_HR(hr = pSelf->pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf)); + CHECK_HR(hr = pSurf->LockRect(&pSelf->rcLock, NULL, D3DLOCK_NOSYSLOCK )); + + // Fast copy() using MMX, SSE, or SSE2 + // Only available on Vista or later: Use LoadLibrary() to get a pointer to the function + /*hr = MFCopyImage( + (BYTE*)pSelf->rcLock.pBits, + pSelf->rcLock.Pitch, + (BYTE*)buffer, + (pSelf->nNegWidth << 2), + (pSelf->nNegWidth << 2), + pSelf->nNegHeight + );*/ + + if(pSelf->rcLock.Pitch == (pSelf->nNegWidth << 2)) { + memcpy(pSelf->rcLock.pBits, buffer, size); + } + else { + const BYTE* pSrcPtr = (const BYTE*)buffer; + BYTE* pDstPtr = (BYTE*)pSelf->rcLock.pBits; + UINT32 nDstPitch = pSelf->rcLock.Pitch; + UINT32 nSrcPitch = (pSelf->nNegWidth << 2); + for(UINT32 i = 0; i < pSelf->nNegHeight; ++i) { + memcpy(pDstPtr, pSrcPtr, nSrcPitch); + pDstPtr += nDstPitch; + pSrcPtr += nSrcPitch; + } + } + + if(FAILED(hr)) { + // unlock() before leaving + pSurf->UnlockRect(); + CHECK_HR(hr); + } + + CHECK_HR(hr = pSurf->UnlockRect()); + + // Color fill the back buffer + CHECK_HR(hr = pSelf->pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBB)); + CHECK_HR(hr = pSelf->pDevice->ColorFill(pBB, NULL, D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF))); + + // Resize keeping aspect ratio and Blit the frame (required) + hr = pSelf->pDevice->StretchRect( + pSurf, + NULL, + pBB, + &pSelf->rcDest/*NULL*/, + D3DTEXF_LINEAR + ); // could fail when display is being resized + if(SUCCEEDED(hr)) { + // Present the frame + CHECK_HR(hr = pSelf->pDevice->Present(NULL, NULL, NULL, NULL)); + } + else { + TSK_DEBUG_INFO("StretchRect returned ...%x", hr); + } bail: - SafeRelease(&pSurf); - SafeRelease(&pBB); + SafeRelease(&pSurf); + SafeRelease(&pBB); - tsk_safeobj_unlock(pSelf); + tsk_safeobj_unlock(pSelf); - return SUCCEEDED(hr) ? 0 : -1; + return SUCCEEDED(hr) ? 0 : -1; } static int plugin_video_dshow_consumer_pause(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - if(!pSelf){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!pSelf->bStarted) - { - TSK_DEBUG_INFO("MF video producer not started"); - return 0; - } + if(!pSelf) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!pSelf->bStarted) { + TSK_DEBUG_INFO("MF video producer not started"); + return 0; + } - HRESULT hr = S_OK; + HRESULT hr = S_OK; - pSelf->bPaused = true; + pSelf->bPaused = true; - return SUCCEEDED(hr) ? 0 : -1; + return SUCCEEDED(hr) ? 0 : -1; } static int plugin_video_dshow_consumer_stop(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* pSelf = (plugin_video_dshow_consumer_t*)self; - if(!pSelf){ + if(!pSelf) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - HRESULT hr = S_OK; - + HRESULT hr = S_OK; + pSelf->bStarted = false; - pSelf->bPaused = false; + pSelf->bPaused = false; - if(pSelf->hWindowFullScreen) - { - ::InvalidateRect(pSelf->hWindowFullScreen, NULL, FALSE); - ::ShowWindow(pSelf->hWindowFullScreen, SW_HIDE); - } + if(pSelf->hWindowFullScreen) { + ::InvalidateRect(pSelf->hWindowFullScreen, NULL, FALSE); + ::ShowWindow(pSelf->hWindowFullScreen, SW_HIDE); + } - // next start() will be called after prepare() - return _plugin_video_dshow_consumer_unprepare(pSelf); + // next start() will be called after prepare() + return _plugin_video_dshow_consumer_unprepare(pSelf); } static int _plugin_video_dshow_consumer_unprepare(plugin_video_dshow_consumer_t* pSelf) { - if(!pSelf){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pSelf) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(pSelf->bStarted) - { - // plugin_win_mf_producer_video_stop(TMEDIA_PRODUCER(pSelf)); - TSK_DEBUG_ERROR("Consumer must be stopped before calling unprepare"); - return -1; - } + if(pSelf->bStarted) { + // plugin_win_mf_producer_video_stop(TMEDIA_PRODUCER(pSelf)); + TSK_DEBUG_ERROR("Consumer must be stopped before calling unprepare"); + return -1; + } - UnhookWindow(pSelf); + UnhookWindow(pSelf); - SafeRelease(&pSelf->pDevice); - SafeRelease(&pSelf->pD3D); - SafeRelease(&pSelf->pSwapChain); + SafeRelease(&pSelf->pDevice); + SafeRelease(&pSelf->pD3D); + SafeRelease(&pSelf->pSwapChain); - pSelf->bPrepared = false; + pSelf->bPrepared = false; - return 0; + return 0; } @@ -510,191 +476,177 @@ static int _plugin_video_dshow_consumer_unprepare(plugin_video_dshow_consumer_t* /* constructor */ static tsk_object_t* plugin_video_dshow_consumer_ctor(tsk_object_t * self, va_list * app) { - plugin_video_dshow_consumer_t *pSelf = (plugin_video_dshow_consumer_t *)self; - if(pSelf) - { - /* init base */ - tmedia_consumer_init(TMEDIA_CONSUMER(pSelf)); - TMEDIA_CONSUMER(pSelf)->video.display.chroma = tmedia_chroma_rgb32; - TMEDIA_CONSUMER(pSelf)->decoder.codec_id = tmedia_codec_id_none; // means accept RAW fames - - /* init self */ - tsk_safeobj_init(pSelf); - TMEDIA_CONSUMER(pSelf)->video.fps = 15; - TMEDIA_CONSUMER(pSelf)->video.display.width = 0; // use codec value - TMEDIA_CONSUMER(pSelf)->video.display.height = 0; // use codec value - TMEDIA_CONSUMER(pSelf)->video.display.auto_resize = tsk_true; - - pSelf->pixelAR.Denominator = pSelf->pixelAR.Numerator = 1; - } - return self; + plugin_video_dshow_consumer_t *pSelf = (plugin_video_dshow_consumer_t *)self; + if(pSelf) { + /* init base */ + tmedia_consumer_init(TMEDIA_CONSUMER(pSelf)); + TMEDIA_CONSUMER(pSelf)->video.display.chroma = tmedia_chroma_rgb32; + TMEDIA_CONSUMER(pSelf)->decoder.codec_id = tmedia_codec_id_none; // means accept RAW fames + + /* init self */ + tsk_safeobj_init(pSelf); + TMEDIA_CONSUMER(pSelf)->video.fps = 15; + TMEDIA_CONSUMER(pSelf)->video.display.width = 0; // use codec value + TMEDIA_CONSUMER(pSelf)->video.display.height = 0; // use codec value + TMEDIA_CONSUMER(pSelf)->video.display.auto_resize = tsk_true; + + pSelf->pixelAR.Denominator = pSelf->pixelAR.Numerator = 1; + } + return self; } /* destructor */ static tsk_object_t* plugin_video_dshow_consumer_dtor(tsk_object_t * self) -{ - plugin_video_dshow_consumer_t *pSelf = (plugin_video_dshow_consumer_t *)self; - if (pSelf) { - /* stop */ - if (pSelf->bStarted) - { - plugin_video_dshow_consumer_stop(TMEDIA_CONSUMER(pSelf)); - } - - /* deinit base */ - tmedia_consumer_deinit(TMEDIA_CONSUMER(pSelf)); - /* deinit self */ - _plugin_video_dshow_consumer_unprepare(pSelf); - tsk_safeobj_deinit(pSelf); - } - - return self; +{ + plugin_video_dshow_consumer_t *pSelf = (plugin_video_dshow_consumer_t *)self; + if (pSelf) { + /* stop */ + if (pSelf->bStarted) { + plugin_video_dshow_consumer_stop(TMEDIA_CONSUMER(pSelf)); + } + + /* deinit base */ + tmedia_consumer_deinit(TMEDIA_CONSUMER(pSelf)); + /* deinit self */ + _plugin_video_dshow_consumer_unprepare(pSelf); + tsk_safeobj_deinit(pSelf); + } + + return self; } /* object definition */ -static const tsk_object_def_t plugin_video_dshow_consumer_def_s = -{ - sizeof(plugin_video_dshow_consumer_t), - plugin_video_dshow_consumer_ctor, - plugin_video_dshow_consumer_dtor, - tsk_null, +static const tsk_object_def_t plugin_video_dshow_consumer_def_s = { + sizeof(plugin_video_dshow_consumer_t), + plugin_video_dshow_consumer_ctor, + plugin_video_dshow_consumer_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_consumer_plugin_def_t plugin_video_dshow_consumer_plugin_def_s = -{ - &plugin_video_dshow_consumer_def_s, - - tmedia_video, - "Microsoft DirectShow consumer (D3D9)", - - plugin_video_dshow_consumer_set, - plugin_video_dshow_consumer_prepare, - plugin_video_dshow_consumer_start, - plugin_video_dshow_consumer_consume, - plugin_video_dshow_consumer_pause, - plugin_video_dshow_consumer_stop +static const tmedia_consumer_plugin_def_t plugin_video_dshow_consumer_plugin_def_s = { + &plugin_video_dshow_consumer_def_s, + + tmedia_video, + "Microsoft DirectShow consumer (D3D9)", + + plugin_video_dshow_consumer_set, + plugin_video_dshow_consumer_prepare, + plugin_video_dshow_consumer_start, + plugin_video_dshow_consumer_consume, + plugin_video_dshow_consumer_pause, + plugin_video_dshow_consumer_stop }; const tmedia_consumer_plugin_def_t *plugin_video_dshow_consumer_plugin_def_t = &plugin_video_dshow_consumer_plugin_def_s; // Helper functions static HRESULT CreateDeviceD3D9( - HWND hWnd, - IDirect3DDevice9** ppDevice, - IDirect3D9 **ppD3D, - D3DPRESENT_PARAMETERS &d3dpp - ) + HWND hWnd, + IDirect3DDevice9** ppDevice, + IDirect3D9 **ppD3D, + D3DPRESENT_PARAMETERS &d3dpp +) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; D3DDISPLAYMODE mode = { 0 }; - D3DPRESENT_PARAMETERS pp = {0}; - - if(!ppDevice || *ppDevice || !ppD3D || *ppD3D) - { - CHECK_HR(hr = E_POINTER); - } - - if(!(*ppD3D = Direct3DCreate9(D3D_SDK_VERSION))) - { + D3DPRESENT_PARAMETERS pp = {0}; + + if(!ppDevice || *ppDevice || !ppD3D || *ppD3D) { + CHECK_HR(hr = E_POINTER); + } + + if(!(*ppD3D = Direct3DCreate9(D3D_SDK_VERSION))) { CHECK_HR(hr = E_OUTOFMEMORY); } CHECK_HR(hr = (*ppD3D)->GetAdapterDisplayMode( - D3DADAPTER_DEFAULT, - &mode - )); + D3DADAPTER_DEFAULT, + &mode + )); CHECK_HR(hr = (*ppD3D)->CheckDeviceType( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - mode.Format, - D3DFMT_X8R8G8B8, - TRUE // windowed - )); + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + mode.Format, + D3DFMT_X8R8G8B8, + TRUE // windowed + )); pp.BackBufferFormat = D3DFMT_X8R8G8B8; pp.SwapEffect = D3DSWAPEFFECT_DISCARD; pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - pp.Windowed = TRUE; + pp.Windowed = TRUE; pp.hDeviceWindow = hWnd; CHECK_HR(hr = (*ppD3D)->CreateDevice( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - hWnd, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &pp, - ppDevice - )); + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + hWnd, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &pp, + ppDevice + )); - d3dpp = pp; + d3dpp = pp; bail: - if(FAILED(hr)) - { - SafeRelease(ppD3D); - SafeRelease(ppDevice); - } + if(FAILED(hr)) { + SafeRelease(ppD3D); + SafeRelease(ppDevice); + } return hr; } static HRESULT TestCooperativeLevel( - struct plugin_video_dshow_consumer_s *pSelf - ) + struct plugin_video_dshow_consumer_s *pSelf +) { - HRESULT hr = S_OK; - - if (!pSelf || !pSelf->pDevice) - { - CHECK_HR(hr = E_POINTER); - } - - switch((hr = pSelf->pDevice->TestCooperativeLevel())) - { - case D3D_OK: - { - break; - } - - case D3DERR_DEVICELOST: - { - hr = S_OK; - break; - } - - case D3DERR_DEVICENOTRESET: - { - hr = ResetDevice(pSelf, TRUE); - break; - } - - default: - { - break; - } - } - - CHECK_HR(hr); + HRESULT hr = S_OK; + + if (!pSelf || !pSelf->pDevice) { + CHECK_HR(hr = E_POINTER); + } + + switch((hr = pSelf->pDevice->TestCooperativeLevel())) { + case D3D_OK: { + break; + } + + case D3DERR_DEVICELOST: { + hr = S_OK; + break; + } + + case D3DERR_DEVICENOTRESET: { + hr = ResetDevice(pSelf, TRUE); + break; + } + + default: { + break; + } + } + + CHECK_HR(hr); bail: return hr; } static HRESULT CreateSwapChain( - HWND hWnd, - UINT32 nFrameWidth, - UINT32 nFrameHeight, - IDirect3DDevice9* pDevice, - IDirect3DSwapChain9 **ppSwapChain - ) + HWND hWnd, + UINT32 nFrameWidth, + UINT32 nFrameHeight, + IDirect3DDevice9* pDevice, + IDirect3DSwapChain9 **ppSwapChain +) { HRESULT hr = S_OK; D3DPRESENT_PARAMETERS pp = { 0 }; - if(!pDevice || !ppSwapChain || *ppSwapChain) - { - CHECK_HR(hr = E_POINTER); - } - - pp.BackBufferWidth = nFrameWidth; + if(!pDevice || !ppSwapChain || *ppSwapChain) { + CHECK_HR(hr = E_POINTER); + } + + pp.BackBufferWidth = nFrameWidth; pp.BackBufferHeight = nFrameHeight; pp.Windowed = TRUE; pp.SwapEffect = D3DSWAPEFFECT_FLIP; @@ -706,7 +658,7 @@ static HRESULT CreateSwapChain( pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; pp.BackBufferCount = NUM_BACK_BUFFERS; - CHECK_HR(hr = pDevice->CreateAdditionalSwapChain(&pp, ppSwapChain)); + CHECK_HR(hr = pDevice->CreateAdditionalSwapChain(&pp, ppSwapChain)); bail: return hr; @@ -714,7 +666,7 @@ bail: static inline HWND Window(struct plugin_video_dshow_consumer_s *pSelf) { - return pSelf ? (pSelf->bFullScreen ? pSelf->hWindowFullScreen : pSelf->hWindow) : NULL; + return pSelf ? (pSelf->bFullScreen ? pSelf->hWindowFullScreen : pSelf->hWindow) : NULL; } static inline LONG Width(const RECT& r) @@ -743,17 +695,14 @@ static inline RECT CorrectAspectRatio(const RECT& src, const DSRatio& srcPAR) // Start with a rectangle the same size as src, but offset to the origin (0,0). RECT rc = {0, 0, src.right - src.left, src.bottom - src.top}; - if ((srcPAR.Numerator != 1) || (srcPAR.Denominator != 1)) - { + if ((srcPAR.Numerator != 1) || (srcPAR.Denominator != 1)) { // Correct for the source's PAR. - if (srcPAR.Numerator > srcPAR.Denominator) - { + if (srcPAR.Numerator > srcPAR.Denominator) { // The source has "wide" pixels, so stretch the width. rc.right = MulDiv(rc.right, srcPAR.Numerator, srcPAR.Denominator); } - else if (srcPAR.Numerator < srcPAR.Denominator) - { + else if (srcPAR.Numerator < srcPAR.Denominator) { // The source has "tall" pixels, so stretch the height. rc.bottom = MulDiv(rc.bottom, srcPAR.Denominator, srcPAR.Numerator); } @@ -816,266 +765,242 @@ static inline RECT LetterBoxRect(const RECT& rcSrc, const RECT& rcDst) static inline HRESULT UpdateDestinationRect(plugin_video_dshow_consumer_t *pSelf, BOOL bForce /*= FALSE*/) { - HRESULT hr = S_OK; - HWND hwnd = Window(pSelf); - - if(!pSelf) - { - CHECK_HR(hr = E_POINTER); - } - - if(!hwnd) - { - CHECK_HR(hr = E_HANDLE); - } + HRESULT hr = S_OK; + HWND hwnd = Window(pSelf); + + if(!pSelf) { + CHECK_HR(hr = E_POINTER); + } + + if(!hwnd) { + CHECK_HR(hr = E_HANDLE); + } RECT rcClient; - GetClientRect(hwnd, &rcClient); + GetClientRect(hwnd, &rcClient); - // only update destination if window size changed - if(bForce || (rcClient.bottom != pSelf->rcWindow.bottom || rcClient.left != pSelf->rcWindow.left || rcClient.right != pSelf->rcWindow.right || rcClient.top != pSelf->rcWindow.top)) - { - CHECK_HR(hr = ResetDevice(pSelf)); + // only update destination if window size changed + if(bForce || (rcClient.bottom != pSelf->rcWindow.bottom || rcClient.left != pSelf->rcWindow.left || rcClient.right != pSelf->rcWindow.right || rcClient.top != pSelf->rcWindow.top)) { + CHECK_HR(hr = ResetDevice(pSelf)); - pSelf->rcWindow = rcClient; + pSelf->rcWindow = rcClient; #if 1 - RECT rcSrc = { 0, 0, pSelf->nNegWidth, pSelf->nNegHeight }; - rcSrc = CorrectAspectRatio(rcSrc, pSelf->pixelAR); - pSelf->rcDest = LetterBoxRect(rcSrc, rcClient); + RECT rcSrc = { 0, 0, pSelf->nNegWidth, pSelf->nNegHeight }; + rcSrc = CorrectAspectRatio(rcSrc, pSelf->pixelAR); + pSelf->rcDest = LetterBoxRect(rcSrc, rcClient); #else - long w = rcClient.right - rcClient.left; - long h = rcClient.bottom - rcClient.top; - float ratio = ((float)pSelf->nNegWidth/(float)pSelf->nNegHeight); - // (w/h)=ratio => - // 1) h=w/ratio - // and - // 2) w=h*ratio - pSelf->rcDest.right = (int)(w/ratio) > h ? (int)(h * ratio) : w; - pSelf->rcDest.bottom = (int)(pSelf->rcDest.right/ratio) > h ? h : (int)(pSelf->rcDest.right/ratio); - pSelf->rcDest.left = ((w - pSelf->rcDest.right) >> 1); - pSelf->rcDest.top = ((h - pSelf->rcDest.bottom) >> 1); + long w = rcClient.right - rcClient.left; + long h = rcClient.bottom - rcClient.top; + float ratio = ((float)pSelf->nNegWidth/(float)pSelf->nNegHeight); + // (w/h)=ratio => + // 1) h=w/ratio + // and + // 2) w=h*ratio + pSelf->rcDest.right = (int)(w/ratio) > h ? (int)(h * ratio) : w; + pSelf->rcDest.bottom = (int)(pSelf->rcDest.right/ratio) > h ? h : (int)(pSelf->rcDest.right/ratio); + pSelf->rcDest.left = ((w - pSelf->rcDest.right) >> 1); + pSelf->rcDest.top = ((h - pSelf->rcDest.bottom) >> 1); #endif - //::InvalidateRect(hwnd, NULL, FALSE); - } + //::InvalidateRect(hwnd, NULL, FALSE); + } bail: - return hr; + return hr; } static HRESULT ResetDevice(plugin_video_dshow_consumer_t *pSelf, BOOL bUpdateDestinationRect /*= FALSE*/) { HRESULT hr = S_OK; - tsk_safeobj_lock(pSelf); + tsk_safeobj_lock(pSelf); - HWND hWnd = Window(pSelf); + HWND hWnd = Window(pSelf); - if (pSelf->pDevice) - { + if (pSelf->pDevice) { D3DPRESENT_PARAMETERS d3dpp = pSelf->d3dpp; hr = pSelf->pDevice->Reset(&d3dpp); - if (FAILED(hr)) - { + if (FAILED(hr)) { SafeRelease(&pSelf->pDevice); - SafeRelease(&pSelf->pD3D); - SafeRelease(&pSelf->pSwapChain); + SafeRelease(&pSelf->pD3D); + SafeRelease(&pSelf->pSwapChain); } } - if (pSelf->pDevice == NULL && hWnd) - { + if (pSelf->pDevice == NULL && hWnd) { CHECK_HR(hr = CreateDeviceD3D9(hWnd, &pSelf->pDevice, &pSelf->pD3D, pSelf->d3dpp)); - CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); - } + CHECK_HR(hr = CreateSwapChain(hWnd, pSelf->nNegWidth, pSelf->nNegHeight, pSelf->pDevice, &pSelf->pSwapChain)); + } - if(bUpdateDestinationRect) // endless loop guard - { - CHECK_HR(hr = UpdateDestinationRect(pSelf)); - } + if(bUpdateDestinationRect) { // endless loop guard + CHECK_HR(hr = UpdateDestinationRect(pSelf)); + } bail: - tsk_safeobj_unlock(pSelf); + tsk_safeobj_unlock(pSelf); - return hr; + return hr; } static HRESULT SetFullscreen(struct plugin_video_dshow_consumer_s *pSelf, BOOL bFullScreen) { - HRESULT hr = S_OK; - if(!pSelf) - { - CHECK_HR(hr = E_POINTER); - } - - if(pSelf->bFullScreen != bFullScreen) - { - tsk_safeobj_lock(pSelf); - if(bFullScreen) - { - HWND hWnd = CreateFullScreenWindow(pSelf); - if(hWnd) - { - ::ShowWindow(hWnd, SW_SHOWDEFAULT); - ::UpdateWindow(hWnd); - } - } - else if(pSelf->hWindowFullScreen) - { - ::ShowWindow(pSelf->hWindowFullScreen, SW_HIDE); - } - pSelf->bFullScreen = bFullScreen; - if(pSelf->bPrepared) - { - hr = ResetDevice(pSelf); - } - tsk_safeobj_unlock(pSelf); - - CHECK_HR(hr); - } + HRESULT hr = S_OK; + if(!pSelf) { + CHECK_HR(hr = E_POINTER); + } + + if(pSelf->bFullScreen != bFullScreen) { + tsk_safeobj_lock(pSelf); + if(bFullScreen) { + HWND hWnd = CreateFullScreenWindow(pSelf); + if(hWnd) { + ::ShowWindow(hWnd, SW_SHOWDEFAULT); + ::UpdateWindow(hWnd); + } + } + else if(pSelf->hWindowFullScreen) { + ::ShowWindow(pSelf->hWindowFullScreen, SW_HIDE); + } + pSelf->bFullScreen = bFullScreen; + if(pSelf->bPrepared) { + hr = ResetDevice(pSelf); + } + tsk_safeobj_unlock(pSelf); + + CHECK_HR(hr); + } bail: - return hr; + return hr; } static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch(uMsg) - { - case WM_CREATE: - case WM_SIZE: - case WM_MOVE: - { - struct plugin_video_dshow_consumer_s* pSelf = dynamic_cast<struct plugin_video_dshow_consumer_s*>((struct plugin_video_dshow_consumer_s*)GetPropA(hWnd, "Self")); - if (pSelf) - { - - } - break; - } + switch(uMsg) { + case WM_CREATE: + case WM_SIZE: + case WM_MOVE: { + struct plugin_video_dshow_consumer_s* pSelf = dynamic_cast<struct plugin_video_dshow_consumer_s*>((struct plugin_video_dshow_consumer_s*)GetPropA(hWnd, "Self")); + if (pSelf) { + + } + break; + } #if 0 - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hWnd, &ps); - ps.fErase = FALSE; - - RECT rc; - GetBoundsRect(hdc, &rc, 0); - FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - - EndPaint(hWnd, &ps); - break; - } + case WM_PAINT: { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + ps.fErase = FALSE; + + RECT rc; + GetBoundsRect(hdc, &rc, 0); + FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); + + EndPaint(hWnd, &ps); + break; + } #endif - case WM_ERASEBKGND: - { - return TRUE; // avoid background erasing. - } - - - case WM_CHAR: - case WM_KEYUP: - { - struct plugin_video_dshow_consumer_s* pSelf = dynamic_cast<struct plugin_video_dshow_consumer_s*>((struct plugin_video_dshow_consumer_s*)GetPropA(hWnd, "Self")); - if (pSelf) - { - SetFullscreen(pSelf, FALSE); - } - - break; - } - } - - return DefWindowProc(hWnd, uMsg, wParam, lParam); + case WM_ERASEBKGND: { + return TRUE; // avoid background erasing. + } + + + case WM_CHAR: + case WM_KEYUP: { + struct plugin_video_dshow_consumer_s* pSelf = dynamic_cast<struct plugin_video_dshow_consumer_s*>((struct plugin_video_dshow_consumer_s*)GetPropA(hWnd, "Self")); + if (pSelf) { + SetFullscreen(pSelf, FALSE); + } + + break; + } + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); } static HWND CreateFullScreenWindow(struct plugin_video_dshow_consumer_s *pSelf) { - HRESULT hr = S_OK; - - if(!pSelf) - { - return NULL; - } - - if(!pSelf->hWindowFullScreen) - { - WNDCLASS wc = {0}; - - wc.lpfnWndProc = WndProc; - wc.hInstance = GetModuleHandle(NULL); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"WindowClass"; - RegisterClass(&wc); - pSelf->hWindowFullScreen = ::CreateWindowEx( - NULL, - wc.lpszClassName, - L"Doubango's Video Consumer Fullscreen", - WS_EX_TOPMOST | WS_POPUP, - 0, 0, - GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), - NULL, - NULL, - GetModuleHandle(NULL), - NULL); - - SetPropA(pSelf->hWindowFullScreen, "Self", pSelf); - } - return pSelf->hWindowFullScreen; + HRESULT hr = S_OK; + + if(!pSelf) { + return NULL; + } + + if(!pSelf->hWindowFullScreen) { + WNDCLASS wc = {0}; + + wc.lpfnWndProc = WndProc; + wc.hInstance = GetModuleHandle(NULL); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpszClassName = L"WindowClass"; + RegisterClass(&wc); + pSelf->hWindowFullScreen = ::CreateWindowEx( + NULL, + wc.lpszClassName, + L"Doubango's Video Consumer Fullscreen", + WS_EX_TOPMOST | WS_POPUP, + 0, 0, + GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), + NULL, + NULL, + GetModuleHandle(NULL), + NULL); + + SetPropA(pSelf->hWindowFullScreen, "Self", pSelf); + } + return pSelf->hWindowFullScreen; } static HRESULT HookWindow(plugin_video_dshow_consumer_t *pSelf, HWND hWnd) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; - tsk_safeobj_lock(pSelf); + tsk_safeobj_lock(pSelf); - CHECK_HR(hr = UnhookWindow(pSelf)); + CHECK_HR(hr = UnhookWindow(pSelf)); - if ((pSelf->hWindow = hWnd)) { - pSelf->wndProc = (WNDPROC)SetWindowLongPtr(pSelf->hWindow, GWLP_WNDPROC, (LONG_PTR)WndProc); - if (!pSelf->wndProc) { - TSK_DEBUG_ERROR("HookWindowLongPtr() failed with errcode=%d", GetLastError()); - CHECK_HR(hr = E_FAIL); - } - pSelf->bWindowHooked = TRUE; - } + if ((pSelf->hWindow = hWnd)) { + pSelf->wndProc = (WNDPROC)SetWindowLongPtr(pSelf->hWindow, GWLP_WNDPROC, (LONG_PTR)WndProc); + if (!pSelf->wndProc) { + TSK_DEBUG_ERROR("HookWindowLongPtr() failed with errcode=%d", GetLastError()); + CHECK_HR(hr = E_FAIL); + } + pSelf->bWindowHooked = TRUE; + } bail: - tsk_safeobj_unlock(pSelf); - return S_OK; + tsk_safeobj_unlock(pSelf); + return S_OK; } static HRESULT UnhookWindow(struct plugin_video_dshow_consumer_s *pSelf) { - tsk_safeobj_lock(pSelf); - if (pSelf->hWindow && pSelf->wndProc) { - SetWindowLongPtr(pSelf->hWindow, GWLP_WNDPROC, (LONG_PTR)pSelf->wndProc); - pSelf->wndProc = NULL; - } - if(pSelf->hWindow) - { - ::InvalidateRect(pSelf->hWindow, NULL, FALSE); - } - pSelf->bWindowHooked = FALSE; - tsk_safeobj_unlock(pSelf); - return S_OK; + tsk_safeobj_lock(pSelf); + if (pSelf->hWindow && pSelf->wndProc) { + SetWindowLongPtr(pSelf->hWindow, GWLP_WNDPROC, (LONG_PTR)pSelf->wndProc); + pSelf->wndProc = NULL; + } + if(pSelf->hWindow) { + ::InvalidateRect(pSelf->hWindow, NULL, FALSE); + } + pSelf->bWindowHooked = FALSE; + tsk_safeobj_unlock(pSelf); + return S_OK; } #else /* !PLUGIN_DS_CV_USE_D3D9 */ -typedef struct plugin_video_dshow_consumer_s -{ - TMEDIA_DECLARE_CONSUMER; - - DSDisplay* display; - INT64 window; - - tsk_bool_t plugin_firefox; - tsk_bool_t started; - tsk_bool_t create_on_ui_thread; +typedef struct plugin_video_dshow_consumer_s { + TMEDIA_DECLARE_CONSUMER; + + DSDisplay* display; + INT64 window; + + tsk_bool_t plugin_firefox; + tsk_bool_t started; + tsk_bool_t create_on_ui_thread; } plugin_video_dshow_consumer_t; @@ -1084,166 +1009,170 @@ plugin_video_dshow_consumer_t; /* ============ Media Consumer Interface ================= */ static int plugin_video_dshow_consumer_set(tmedia_consumer_t *self, const tmedia_param_t* param) { - int ret = 0; - - if(!self || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(param->value_type == tmedia_pvt_int64){ - if(tsk_striequals(param->key, "remote-hwnd")){ - DSCONSUMER(self)->window = (INT64)*((int64_t*)param->value); - if(DSCONSUMER(self)->display){ - if(DSCONSUMER(self)->window){ - DSCONSUMER(self)->display->attach(DSCONSUMER(self)->window); - } - else{ - DSCONSUMER(self)->display->detach(); - } - } - } - } - else if(param->value_type == tmedia_pvt_int32){ - if(tsk_striequals(param->key, "fullscreen")){ - if(DSCONSUMER(self)->display){ - DSCONSUMER(self)->display->setFullscreen(*((int32_t*)param->value) != 0); - } - } - else if(tsk_striequals(param->key, "create-on-current-thead")){ - DSCONSUMER(self)->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; - } - else if(tsk_striequals(param->key, "plugin-firefox")){ - DSCONSUMER(self)->plugin_firefox = (*((int32_t*)param->value) != 0); - if(DSCONSUMER(self)->display){ - DSCONSUMER(self)->display->setPluginFirefox((DSCONSUMER(self)->plugin_firefox == tsk_true)); - } - } - } - - return ret; + int ret = 0; + + if(!self || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(param->value_type == tmedia_pvt_int64) { + if(tsk_striequals(param->key, "remote-hwnd")) { + DSCONSUMER(self)->window = (INT64)*((int64_t*)param->value); + if(DSCONSUMER(self)->display) { + if(DSCONSUMER(self)->window) { + DSCONSUMER(self)->display->attach(DSCONSUMER(self)->window); + } + else { + DSCONSUMER(self)->display->detach(); + } + } + } + } + else if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "fullscreen")) { + if(DSCONSUMER(self)->display) { + DSCONSUMER(self)->display->setFullscreen(*((int32_t*)param->value) != 0); + } + } + else if(tsk_striequals(param->key, "create-on-current-thead")) { + DSCONSUMER(self)->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; + } + else if(tsk_striequals(param->key, "plugin-firefox")) { + DSCONSUMER(self)->plugin_firefox = (*((int32_t*)param->value) != 0); + if(DSCONSUMER(self)->display) { + DSCONSUMER(self)->display->setPluginFirefox((DSCONSUMER(self)->plugin_firefox == tsk_true)); + } + } + } + + return ret; } static int plugin_video_dshow_consumer_prepare(tmedia_consumer_t* self, const tmedia_codec_t* codec) { - plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; - - if(!consumer || !codec && codec->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - TMEDIA_CONSUMER(consumer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->in.fps; - TMEDIA_CONSUMER(consumer)->video.in.width = TMEDIA_CODEC_VIDEO(codec)->in.width; - TMEDIA_CONSUMER(consumer)->video.in.height = TMEDIA_CODEC_VIDEO(codec)->in.height; - - if(!TMEDIA_CONSUMER(consumer)->video.display.width){ - TMEDIA_CONSUMER(consumer)->video.display.width = TMEDIA_CONSUMER(consumer)->video.in.width; - } - if(!TMEDIA_CONSUMER(consumer)->video.display.height){ - TMEDIA_CONSUMER(consumer)->video.display.height = TMEDIA_CONSUMER(consumer)->video.in.height; - } - - return 0; + plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; + + if(!consumer || !codec && codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + TMEDIA_CONSUMER(consumer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->in.fps; + TMEDIA_CONSUMER(consumer)->video.in.width = TMEDIA_CODEC_VIDEO(codec)->in.width; + TMEDIA_CONSUMER(consumer)->video.in.height = TMEDIA_CODEC_VIDEO(codec)->in.height; + + if(!TMEDIA_CONSUMER(consumer)->video.display.width) { + TMEDIA_CONSUMER(consumer)->video.display.width = TMEDIA_CONSUMER(consumer)->video.in.width; + } + if(!TMEDIA_CONSUMER(consumer)->video.display.height) { + TMEDIA_CONSUMER(consumer)->video.display.height = TMEDIA_CONSUMER(consumer)->video.in.height; + } + + return 0; } static int plugin_video_dshow_consumer_start(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; - - if(!consumer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(consumer->started){ - return 0; - } - - // create display on UI thread - if(!consumer->display){ - if (consumer->create_on_ui_thread) createOnUIThead(reinterpret_cast<HWND>((void*)consumer->window), (void**)&consumer->display, true, false); - else createOnCurrentThead(reinterpret_cast<HWND>((void*)consumer->window), (void**)&consumer->display, true, false); - - if(!consumer->display){ - TSK_DEBUG_ERROR("Failed to create display"); - return -2; - } - } - - // Set parameters - consumer->display->setPluginFirefox((consumer->plugin_firefox == tsk_true)); - consumer->display->setFps(TMEDIA_CONSUMER(consumer)->video.fps); - // do not change the display size: see hook() - // consumer->display->setSize(TMEDIA_CONSUMER(consumer)->video.display.width, TMEDIA_CONSUMER(consumer)->video.display.height); - if(consumer->window){ - consumer->display->attach(consumer->window); - } - - // Start display - consumer->display->start(); - consumer->started = tsk_true; - - return 0; + plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; + + if(!consumer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(consumer->started) { + return 0; + } + + // create display on UI thread + if(!consumer->display) { + if (consumer->create_on_ui_thread) { + createOnUIThead(reinterpret_cast<HWND>((void*)consumer->window), (void**)&consumer->display, true, false); + } + else { + createOnCurrentThead(reinterpret_cast<HWND>((void*)consumer->window), (void**)&consumer->display, true, false); + } + + if(!consumer->display) { + TSK_DEBUG_ERROR("Failed to create display"); + return -2; + } + } + + // Set parameters + consumer->display->setPluginFirefox((consumer->plugin_firefox == tsk_true)); + consumer->display->setFps(TMEDIA_CONSUMER(consumer)->video.fps); + // do not change the display size: see hook() + // consumer->display->setSize(TMEDIA_CONSUMER(consumer)->video.display.width, TMEDIA_CONSUMER(consumer)->video.display.height); + if(consumer->window) { + consumer->display->attach(consumer->window); + } + + // Start display + consumer->display->start(); + consumer->started = tsk_true; + + return 0; } static int plugin_video_dshow_consumer_consume(tmedia_consumer_t* self, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr) { - plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; - if(consumer && consumer->display && buffer){ - consumer->display->handleVideoFrame(buffer, TMEDIA_CONSUMER(consumer)->video.display.width, TMEDIA_CONSUMER(consumer)->video.display.height); - return 0; - } - else{ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; + if(consumer && consumer->display && buffer) { + consumer->display->handleVideoFrame(buffer, TMEDIA_CONSUMER(consumer)->video.display.width, TMEDIA_CONSUMER(consumer)->video.display.height); + return 0; + } + else { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } } static int plugin_video_dshow_consumer_pause(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; - if(!consumer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!consumer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!consumer->display){ - TSK_DEBUG_ERROR("Invalid internal grabber"); - return -2; - } + if(!consumer->display) { + TSK_DEBUG_ERROR("Invalid internal grabber"); + return -2; + } - //consumer->display->pause(); + //consumer->display->pause(); - return 0; + return 0; } static int plugin_video_dshow_consumer_stop(tmedia_consumer_t* self) { - plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; + plugin_video_dshow_consumer_t* consumer = (plugin_video_dshow_consumer_t*)self; - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!consumer->started){ - return 0; - } + if(!consumer->started) { + return 0; + } - if(!consumer->display){ - TSK_DEBUG_ERROR("Invalid internal display"); - return -2; - } + if(!consumer->display) { + TSK_DEBUG_ERROR("Invalid internal display"); + return -2; + } - TSK_DEBUG_INFO("Before stopping DirectShow consumer"); - consumer->display->stop(); - consumer->started = tsk_false; - TSK_DEBUG_INFO("After stopping DirectShow consumer"); + TSK_DEBUG_INFO("Before stopping DirectShow consumer"); + consumer->display->stop(); + consumer->started = tsk_false; + TSK_DEBUG_INFO("After stopping DirectShow consumer"); - return 0; + return 0; } @@ -1253,65 +1182,63 @@ static int plugin_video_dshow_consumer_stop(tmedia_consumer_t* self) /* constructor */ static tsk_object_t* plugin_video_dshow_consumer_ctor(tsk_object_t * self, va_list * app) { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - plugin_video_dshow_consumer_t *consumer = (plugin_video_dshow_consumer_t *)self; - if(consumer){ - /* init base */ - tmedia_consumer_init(TMEDIA_CONSUMER(consumer)); - TMEDIA_CONSUMER(consumer)->video.display.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 - - /* init self */ - consumer->create_on_ui_thread = tsk_true; - TMEDIA_CONSUMER(consumer)->video.fps = 15; - TMEDIA_CONSUMER(consumer)->video.display.width = 352; - TMEDIA_CONSUMER(consumer)->video.display.height = 288; - TMEDIA_CONSUMER(consumer)->video.display.auto_resize = tsk_true; - } - return self; + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + plugin_video_dshow_consumer_t *consumer = (plugin_video_dshow_consumer_t *)self; + if(consumer) { + /* init base */ + tmedia_consumer_init(TMEDIA_CONSUMER(consumer)); + TMEDIA_CONSUMER(consumer)->video.display.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 + + /* init self */ + consumer->create_on_ui_thread = tsk_true; + TMEDIA_CONSUMER(consumer)->video.fps = 15; + TMEDIA_CONSUMER(consumer)->video.display.width = 352; + TMEDIA_CONSUMER(consumer)->video.display.height = 288; + TMEDIA_CONSUMER(consumer)->video.display.auto_resize = tsk_true; + } + return self; } /* destructor */ static tsk_object_t* plugin_video_dshow_consumer_dtor(tsk_object_t * self) -{ - plugin_video_dshow_consumer_t *consumer = (plugin_video_dshow_consumer_t *)self; - if(consumer){ - - /* stop */ - if(consumer->started){ - plugin_video_dshow_consumer_stop((tmedia_consumer_t*)self); - } - - /* deinit base */ - tmedia_consumer_deinit(TMEDIA_CONSUMER(consumer)); - /* deinit self */ - SAFE_DELETE_PTR(consumer->display); - - } - - return self; +{ + plugin_video_dshow_consumer_t *consumer = (plugin_video_dshow_consumer_t *)self; + if(consumer) { + + /* stop */ + if(consumer->started) { + plugin_video_dshow_consumer_stop((tmedia_consumer_t*)self); + } + + /* deinit base */ + tmedia_consumer_deinit(TMEDIA_CONSUMER(consumer)); + /* deinit self */ + SAFE_DELETE_PTR(consumer->display); + + } + + return self; } /* object definition */ -static const tsk_object_def_t plugin_video_dshow_consumer_def_s = -{ - sizeof(plugin_video_dshow_consumer_t), - plugin_video_dshow_consumer_ctor, - plugin_video_dshow_consumer_dtor, - tsk_null, +static const tsk_object_def_t plugin_video_dshow_consumer_def_s = { + sizeof(plugin_video_dshow_consumer_t), + plugin_video_dshow_consumer_ctor, + plugin_video_dshow_consumer_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_consumer_plugin_def_t plugin_video_dshow_consumer_plugin_def_s = -{ - &plugin_video_dshow_consumer_def_s, - - tmedia_video, - "Microsoft DirectShow consumer (using custom source)", - - plugin_video_dshow_consumer_set, - plugin_video_dshow_consumer_prepare, - plugin_video_dshow_consumer_start, - plugin_video_dshow_consumer_consume, - plugin_video_dshow_consumer_pause, - plugin_video_dshow_consumer_stop +static const tmedia_consumer_plugin_def_t plugin_video_dshow_consumer_plugin_def_s = { + &plugin_video_dshow_consumer_def_s, + + tmedia_video, + "Microsoft DirectShow consumer (using custom source)", + + plugin_video_dshow_consumer_set, + plugin_video_dshow_consumer_prepare, + plugin_video_dshow_consumer_start, + plugin_video_dshow_consumer_consume, + plugin_video_dshow_consumer_pause, + plugin_video_dshow_consumer_stop }; const tmedia_consumer_plugin_def_t *plugin_video_dshow_consumer_plugin_def_t = &plugin_video_dshow_consumer_plugin_def_s; diff --git a/plugins/pluginDirectShow/plugin_video_dshow_producer.cxx b/plugins/pluginDirectShow/plugin_video_dshow_producer.cxx index 61aa929..77f6bfb 100755 --- a/plugins/pluginDirectShow/plugin_video_dshow_producer.cxx +++ b/plugins/pluginDirectShow/plugin_video_dshow_producer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2011-2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,187 +26,190 @@ #define DSPRODUCER(self) ((plugin_video_dshow_producer_t*)(self)) -typedef struct plugin_video_dshow_producer_s -{ - TMEDIA_DECLARE_PRODUCER; - - DSGrabber* grabber; - INT64 previewHwnd; - - tsk_bool_t plugin_firefox; - tsk_bool_t started; - tsk_bool_t mute; - tsk_bool_t create_on_ui_thread; +typedef struct plugin_video_dshow_producer_s { + TMEDIA_DECLARE_PRODUCER; + + DSGrabber* grabber; + INT64 previewHwnd; + + tsk_bool_t plugin_firefox; + tsk_bool_t started; + tsk_bool_t mute; + tsk_bool_t create_on_ui_thread; } plugin_video_dshow_producer_t; // Producer callback (From DirectShow Grabber to our plugin) static int plugin_video_dshow_plugin_cb(const void* callback_data, const void* buffer, tsk_size_t size) { - const plugin_video_dshow_producer_t* producer = (const plugin_video_dshow_producer_t*)callback_data; + const plugin_video_dshow_producer_t* producer = (const plugin_video_dshow_producer_t*)callback_data; - if(producer && TMEDIA_PRODUCER(producer)->enc_cb.callback){ - TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, buffer, size); - } + if(producer && TMEDIA_PRODUCER(producer)->enc_cb.callback) { + TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, buffer, size); + } - return 0; + return 0; } /* ============ Media Producer Interface ================= */ static int plugin_video_dshow_producer_set(tmedia_producer_t *self, const tmedia_param_t* param) { - int ret = 0; - plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; - - if(!producer || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(param->value_type == tmedia_pvt_int64){ - if(tsk_striequals(param->key, "local-hwnd")){ - DSPRODUCER(producer)->previewHwnd = (INT64)*((int64_t*)param->value); - if(DSPRODUCER(producer)->grabber && DSPRODUCER(self)->grabber->preview){ - DSPRODUCER(producer)->grabber->preview->attach(DSPRODUCER(producer)->previewHwnd); - } - } - } - else if(param->value_type == tmedia_pvt_int32){ - if(tsk_striequals(param->key, "mute")){ - producer->mute = (TSK_TO_INT32((uint8_t*)param->value) != 0); - if(producer->started){ - if (producer->mute) { - producer->grabber->pause(); - } - else{ - producer->grabber->start(); - } - } - } - else if(tsk_striequals(param->key, "create-on-current-thead")){ - producer->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; - } - else if(tsk_striequals(param->key, "plugin-firefox")){ - producer->plugin_firefox = (*((int32_t*)param->value) != 0); - if(producer->grabber){ - producer->grabber->setPluginFirefox((producer->plugin_firefox == tsk_true)); - } - } - } - - return ret; + int ret = 0; + plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; + + if(!producer || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(param->value_type == tmedia_pvt_int64) { + if(tsk_striequals(param->key, "local-hwnd")) { + DSPRODUCER(producer)->previewHwnd = (INT64)*((int64_t*)param->value); + if(DSPRODUCER(producer)->grabber && DSPRODUCER(self)->grabber->preview) { + DSPRODUCER(producer)->grabber->preview->attach(DSPRODUCER(producer)->previewHwnd); + } + } + } + else if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "mute")) { + producer->mute = (TSK_TO_INT32((uint8_t*)param->value) != 0); + if(producer->started) { + if (producer->mute) { + producer->grabber->pause(); + } + else { + producer->grabber->start(); + } + } + } + else if(tsk_striequals(param->key, "create-on-current-thead")) { + producer->create_on_ui_thread = *((int32_t*)param->value) ? tsk_false : tsk_true; + } + else if(tsk_striequals(param->key, "plugin-firefox")) { + producer->plugin_firefox = (*((int32_t*)param->value) != 0); + if(producer->grabber) { + producer->grabber->setPluginFirefox((producer->plugin_firefox == tsk_true)); + } + } + } + + return ret; } static int plugin_video_dshow_producer_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec) { - plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; - - if(!producer || !codec && codec->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - TMEDIA_PRODUCER(producer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->out.fps; - TMEDIA_PRODUCER(producer)->video.width = TMEDIA_CODEC_VIDEO(codec)->out.width; - TMEDIA_PRODUCER(producer)->video.height = TMEDIA_CODEC_VIDEO(codec)->out.height; - - return 0; + plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; + + if(!producer || !codec && codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + TMEDIA_PRODUCER(producer)->video.fps = TMEDIA_CODEC_VIDEO(codec)->out.fps; + TMEDIA_PRODUCER(producer)->video.width = TMEDIA_CODEC_VIDEO(codec)->out.width; + TMEDIA_PRODUCER(producer)->video.height = TMEDIA_CODEC_VIDEO(codec)->out.height; + + return 0; } static int plugin_video_dshow_producer_start(tmedia_producer_t* self) { - plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; - - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (producer->started) { - return 0; - } - - // create grabber on UI thread - if (!producer->grabber) { - static BOOL __isDisplayFalse = FALSE; - static BOOL __isScreenCastFalse = FALSE; - if(producer->create_on_ui_thread) createOnUIThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastFalse); - else createOnCurrentThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastFalse); - if (!producer->grabber) { - TSK_DEBUG_ERROR("Failed to create grabber"); - return -2; - } - } - producer->grabber->setPluginFirefox((producer->plugin_firefox == tsk_true)); - - //set Source device - producer->grabber->setCaptureDevice("Null"); - - // set parameters - producer->grabber->setCaptureParameters((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height, TMEDIA_PRODUCER(producer)->video.fps); - - // set callback function - producer->grabber->setCallback(plugin_video_dshow_plugin_cb, producer); - - // attach preview - if(producer->grabber->preview){ - if(producer->previewHwnd){ - producer->grabber->preview->attach(producer->previewHwnd); - } - producer->grabber->preview->setSize((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height); - } - - // start grabber - if(!producer->mute){ - producer->grabber->start(); - } - producer->started = tsk_true; - - return 0; + plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; + + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (producer->started) { + return 0; + } + + // create grabber on UI thread + if (!producer->grabber) { + static BOOL __isDisplayFalse = FALSE; + static BOOL __isScreenCastFalse = FALSE; + if(producer->create_on_ui_thread) { + createOnUIThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastFalse); + } + else { + createOnCurrentThead(reinterpret_cast<HWND>((void*)DSPRODUCER(producer)->previewHwnd), (void**)&producer->grabber, __isDisplayFalse, __isScreenCastFalse); + } + if (!producer->grabber) { + TSK_DEBUG_ERROR("Failed to create grabber"); + return -2; + } + } + producer->grabber->setPluginFirefox((producer->plugin_firefox == tsk_true)); + + //set Source device + producer->grabber->setCaptureDevice("Null"); + + // set parameters + producer->grabber->setCaptureParameters((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height, TMEDIA_PRODUCER(producer)->video.fps); + + // set callback function + producer->grabber->setCallback(plugin_video_dshow_plugin_cb, producer); + + // attach preview + if(producer->grabber->preview) { + if(producer->previewHwnd) { + producer->grabber->preview->attach(producer->previewHwnd); + } + producer->grabber->preview->setSize((int)TMEDIA_PRODUCER(producer)->video.width, (int)TMEDIA_PRODUCER(producer)->video.height); + } + + // start grabber + if(!producer->mute) { + producer->grabber->start(); + } + producer->started = tsk_true; + + return 0; } static int plugin_video_dshow_producer_pause(tmedia_producer_t* self) { - plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; + plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!producer->grabber){ - TSK_DEBUG_ERROR("Invalid internal grabber"); - return -2; - } + if(!producer->grabber) { + TSK_DEBUG_ERROR("Invalid internal grabber"); + return -2; + } - producer->grabber->pause(); + producer->grabber->pause(); - return 0; + return 0; } static int plugin_video_dshow_producer_stop(tmedia_producer_t* self) { - plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; + plugin_video_dshow_producer_t* producer = (plugin_video_dshow_producer_t*)self; - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!producer->started){ - return 0; - } + if(!producer->started) { + return 0; + } - if(!producer->grabber){ - TSK_DEBUG_ERROR("Invalid internal grabber"); - return -2; - } + if(!producer->grabber) { + TSK_DEBUG_ERROR("Invalid internal grabber"); + return -2; + } - producer->grabber->stop(); - producer->started = tsk_false; + producer->grabber->stop(); + producer->started = tsk_false; - return 0; + return 0; } @@ -215,62 +218,61 @@ static int plugin_video_dshow_producer_stop(tmedia_producer_t* self) // /* constructor */ static tsk_object_t* plugin_video_dshow_producer_ctor(tsk_object_t * self, va_list * app) -{ plugin_video_dshow_producer_t *producer = (plugin_video_dshow_producer_t *)self; - if (producer) { - /* init base */ - tmedia_producer_init(TMEDIA_PRODUCER(producer)); - TMEDIA_PRODUCER(producer)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 - /* init self with default values*/ - producer->create_on_ui_thread = tsk_true; - TMEDIA_PRODUCER(producer)->video.fps = 15; - TMEDIA_PRODUCER(producer)->video.width = 352; - TMEDIA_PRODUCER(producer)->video.height = 288; - } - return self; +{ + plugin_video_dshow_producer_t *producer = (plugin_video_dshow_producer_t *)self; + if (producer) { + /* init base */ + tmedia_producer_init(TMEDIA_PRODUCER(producer)); + TMEDIA_PRODUCER(producer)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24 + /* init self with default values*/ + producer->create_on_ui_thread = tsk_true; + TMEDIA_PRODUCER(producer)->video.fps = 15; + TMEDIA_PRODUCER(producer)->video.width = 352; + TMEDIA_PRODUCER(producer)->video.height = 288; + } + return self; } /* destructor */ static tsk_object_t* plugin_video_dshow_producer_dtor(tsk_object_t * self) -{ - plugin_video_dshow_producer_t *producer = (plugin_video_dshow_producer_t *)self; - if(producer){ - /* stop */ - if(producer->started){ - plugin_video_dshow_producer_stop((tmedia_producer_t*)self); - } - - /* for safety */ - if(producer->grabber){ - producer->grabber->setCallback(tsk_null, tsk_null); - } - - /* deinit base */ - tmedia_producer_deinit(TMEDIA_PRODUCER(producer)); - /* deinit self */ - SAFE_DELETE_PTR(producer->grabber); - } - - return self; +{ + plugin_video_dshow_producer_t *producer = (plugin_video_dshow_producer_t *)self; + if(producer) { + /* stop */ + if(producer->started) { + plugin_video_dshow_producer_stop((tmedia_producer_t*)self); + } + + /* for safety */ + if(producer->grabber) { + producer->grabber->setCallback(tsk_null, tsk_null); + } + + /* deinit base */ + tmedia_producer_deinit(TMEDIA_PRODUCER(producer)); + /* deinit self */ + SAFE_DELETE_PTR(producer->grabber); + } + + return self; } /* object definition */ -static const tsk_object_def_t plugin_video_dshow_producer_def_s = -{ - sizeof(plugin_video_dshow_producer_t), - plugin_video_dshow_producer_ctor, - plugin_video_dshow_producer_dtor, - tsk_null, +static const tsk_object_def_t plugin_video_dshow_producer_def_s = { + sizeof(plugin_video_dshow_producer_t), + plugin_video_dshow_producer_ctor, + plugin_video_dshow_producer_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_producer_plugin_def_t plugin_video_dshow_producer_plugin_def_s = -{ - &plugin_video_dshow_producer_def_s, - - tmedia_video, - "Microsoft DirectShow producer", - - plugin_video_dshow_producer_set, - plugin_video_dshow_producer_prepare, - plugin_video_dshow_producer_start, - plugin_video_dshow_producer_pause, - plugin_video_dshow_producer_stop +static const tmedia_producer_plugin_def_t plugin_video_dshow_producer_plugin_def_s = { + &plugin_video_dshow_producer_def_s, + + tmedia_video, + "Microsoft DirectShow producer", + + plugin_video_dshow_producer_set, + plugin_video_dshow_producer_prepare, + plugin_video_dshow_producer_start, + plugin_video_dshow_producer_pause, + plugin_video_dshow_producer_stop }; const tmedia_producer_plugin_def_t *plugin_video_dshow_producer_plugin_def_t = &plugin_video_dshow_producer_plugin_def_s; |