diff --git a/cmake/OpenCVFindLibsVideo.cmake b/cmake/OpenCVFindLibsVideo.cmake index fec7be4d84..6d6ca62e86 100644 --- a/cmake/OpenCVFindLibsVideo.cmake +++ b/cmake/OpenCVFindLibsVideo.cmake @@ -254,6 +254,7 @@ if(WITH_DSHOW) endif(WITH_DSHOW) # --- VideoInput/Microsoft Media Foundation --- +ocv_clear_vars(HAVE_MSMF) if(WITH_MSMF) check_include_file(Mfapi.h HAVE_MSMF) endif(WITH_MSMF) diff --git a/modules/videoio/CMakeLists.txt b/modules/videoio/CMakeLists.txt index 3a031a9fea..67fd9816ed 100644 --- a/modules/videoio/CMakeLists.txt +++ b/modules/videoio/CMakeLists.txt @@ -42,6 +42,7 @@ if (WIN32 AND HAVE_DSHOW) endif() if (WIN32 AND HAVE_MSMF) + list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.hpp) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_msmf.cpp) endif() diff --git a/modules/videoio/src/cap_msmf.cpp b/modules/videoio/src/cap_msmf.cpp index 2a9ee20a9b..96c06aeb8f 100644 --- a/modules/videoio/src/cap_msmf.cpp +++ b/modules/videoio/src/cap_msmf.cpp @@ -78,7 +78,9 @@ #pragma comment(lib, "mfuuid") #pragma comment(lib, "Strmiids") #pragma comment(lib, "Mfreadwrite") +#if (WINVER >= 0x0602) // Available since Win 8 #pragma comment(lib, "MinCore_Downlevel") +#endif #include @@ -1469,7 +1471,6 @@ void ImageGrabber::stopGrabbing() HRESULT ImageGrabber::startGrabbing(void) { - _ComPtr pEvent = NULL; PROPVARIANT var; PropVariantInit(&var); HRESULT hr = ig_pSession->SetTopology(0, ig_pTopology); @@ -1477,6 +1478,7 @@ HRESULT ImageGrabber::startGrabbing(void) hr = ig_pSession->Start(&GUID_NULL, &var); for(;;) { + _ComPtr pEvent = NULL; HRESULT hrStatus = S_OK; MediaEventType met; if(!ig_pSession) break; @@ -1509,11 +1511,13 @@ HRESULT ImageGrabber::startGrabbing(void) DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID); break; } +#if (WINVER >= 0x0602) // Available since Win 8 if (met == MEVideoCaptureDeviceRemoved) { DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID); break; } +#endif if ((met == MEError) || (met == MENonFatalError)) { pEvent->GetStatus(&hrStatus); @@ -2455,7 +2459,7 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate) fmt = vd_CaptureFormats.find(size); if( fmt != vd_CaptureFormats.end() ) FRM = fmt->second; - else + else if( !vd_CaptureFormats.empty() ) FRM = vd_CaptureFormats.rbegin()->second; if( FRM.empty() ) @@ -3844,18 +3848,25 @@ bool CvCaptureFile_MSMF::open(const char* filename) hr = enumerateCaptureFormats(videoFileSource); } - if (SUCCEEDED(hr)) + if( captureFormats.empty() ) { - hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, (unsigned int)-2, true); + isOpened = false; + } + else + { + if (SUCCEEDED(hr)) + { + hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, (unsigned int)-2, true); + } + + isOpened = SUCCEEDED(hr); } - if (SUCCEEDED(hr)) + if (isOpened) { grabberThread->start(); } - isOpened = SUCCEEDED(hr); - return isOpened; } @@ -3987,7 +3998,9 @@ HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource) goto done; } MediaType MT = FormatReader::Read(pType.Get()); - captureFormats.push_back(MT); + // We can capture only RGB video. + if( MT.MF_MT_SUBTYPE == MFVideoFormat_RGB24 ) + captureFormats.push_back(MT); } done: @@ -4112,7 +4125,7 @@ const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc) return MFVideoFormat_DVSD; break; case CV_FOURCC_MACRO('d', 'v', 's', 'l'): return MFVideoFormat_DVSL; break; -#if (WINVER >= _WIN32_WINNT_WIN8) +#if (WINVER >= 0x0602) case CV_FOURCC_MACRO('H', '2', '6', '3'): // Available only for Win 8 target. return MFVideoFormat_H263; break; #endif diff --git a/modules/videoio/src/cap_msmf.hpp b/modules/videoio/src/cap_msmf.hpp index 38dea5340c..f9e413abb8 100644 --- a/modules/videoio/src/cap_msmf.hpp +++ b/modules/videoio/src/cap_msmf.hpp @@ -333,6 +333,7 @@ MAKE_ENUM(MediaEventType) MediaEventTypePairs[] = { MAKE_ENUM_PAIR(MediaEventType, MEAudioSessionDisconnected), MAKE_ENUM_PAIR(MediaEventType, MEAudioSessionExclusiveModeOverride), MAKE_ENUM_PAIR(MediaEventType, MESinkV1Anchor), +#if (WINVER >= 0x0602) // Available since Win 8 MAKE_ENUM_PAIR(MediaEventType, MECaptureAudioSessionVolumeChanged), MAKE_ENUM_PAIR(MediaEventType, MECaptureAudioSessionDeviceRemoved), MAKE_ENUM_PAIR(MediaEventType, MECaptureAudioSessionFormatChanged), @@ -340,6 +341,7 @@ MAKE_ENUM(MediaEventType) MediaEventTypePairs[] = { MAKE_ENUM_PAIR(MediaEventType, MECaptureAudioSessionExclusiveModeOverride), MAKE_ENUM_PAIR(MediaEventType, MECaptureAudioSessionServerShutdown), MAKE_ENUM_PAIR(MediaEventType, MESinkV2Anchor), +#endif MAKE_ENUM_PAIR(MediaEventType, METrustUnknown), MAKE_ENUM_PAIR(MediaEventType, MEPolicyChanged), MAKE_ENUM_PAIR(MediaEventType, MEContentProtectionMessage), @@ -361,9 +363,11 @@ MAKE_ENUM(MediaEventType) MediaEventTypePairs[] = { MAKE_ENUM_PAIR(MediaEventType, METransformHaveOutput), MAKE_ENUM_PAIR(MediaEventType, METransformDrainComplete), MAKE_ENUM_PAIR(MediaEventType, METransformMarker), +#if (WINVER >= 0x0602) // Available since Win 8 MAKE_ENUM_PAIR(MediaEventType, MEByteStreamCharacteristicsChanged), MAKE_ENUM_PAIR(MediaEventType, MEVideoCaptureDeviceRemoved), MAKE_ENUM_PAIR(MediaEventType, MEVideoCaptureDevicePreempted), +#endif MAKE_ENUM_PAIR(MediaEventType, MEReservedMax) }; MAKE_MAP(MediaEventType) MediaEventTypeMap(MediaEventTypePairs, MediaEventTypePairs + sizeof(MediaEventTypePairs) / sizeof(MediaEventTypePairs[0])); @@ -1044,7 +1048,11 @@ class StreamSink : { public: // IUnknown methods +#if defined(_MSC_VER) && _MSC_VER >= 1700 // '_Outptr_result_nullonfailure_' SAL is avaialable since VS 2012 STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppv) +#else + STDMETHOD(QueryInterface)(REFIID riid, void **ppv) +#endif { if (ppv == nullptr) { return E_POINTER; @@ -2383,7 +2391,11 @@ public: } return cRef; } +#if defined(_MSC_VER) && _MSC_VER >= 1700 // '_Outptr_result_nullonfailure_' SAL is avaialable since VS 2012 STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppv) +#else + STDMETHOD(QueryInterface)(REFIID riid, void **ppv) +#endif { if (ppv == nullptr) { return E_POINTER;