Commit 0c988f00 authored by Juan Carlos Niebles's avatar Juan Carlos Niebles

Merge github.com:Itseez/opencv

parents dc49e115 d1afa0e3
...@@ -4504,8 +4504,8 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3, ...@@ -4504,8 +4504,8 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3,
if (vectorWidths[0] == 1) if (vectorWidths[0] == 1)
{ {
// it's heuristic // it's heuristic
vectorWidths[CV_8U] = vectorWidths[CV_8S] = 16; vectorWidths[CV_8U] = vectorWidths[CV_8S] = 4;
vectorWidths[CV_16U] = vectorWidths[CV_16S] = 8; vectorWidths[CV_16U] = vectorWidths[CV_16S] = 2;
vectorWidths[CV_32S] = vectorWidths[CV_32F] = vectorWidths[CV_64F] = 1; vectorWidths[CV_32S] = vectorWidths[CV_32F] = vectorWidths[CV_64F] = 1;
} }
......
//
// Copyright (C) Microsoft Corporation
// All rights reserved.
// Modified for native C++ WRL support by Gregory Morse
//
// Code in Details namespace is for internal usage within the library code
//
#ifndef _PLATFORM_AGILE_H_
#define _PLATFORM_AGILE_H_
#ifdef _MSC_VER
#pragma once
#endif // _MSC_VER
#include <algorithm>
#include <wrl\client.h>
template <typename T, bool TIsNotAgile> class Agile;
template <typename T>
struct UnwrapAgile
{
static const bool _IsAgile = false;
};
template <typename T>
struct UnwrapAgile<Agile<T, false>>
{
static const bool _IsAgile = true;
};
template <typename T>
struct UnwrapAgile<Agile<T, true>>
{
static const bool _IsAgile = true;
};
#define IS_AGILE(T) UnwrapAgile<T>::_IsAgile
#define __is_winrt_agile(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::FtmBase, T>::value || std::is_base_of<IAgileObject, T>::value) //derived from Microsoft::WRL::FtmBase or IAgileObject
#define __is_win_interface(T) (std::is_base_of<IUnknown, T>::value || std::is_base_of<IInspectable, T>::value) //derived from IUnknown or IInspectable
#define __is_win_class(T) (std::is_same<T, HSTRING__>::value || std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, T>::value) //derived from Microsoft::WRL::RuntimeClass or HSTRING
namespace Details
{
IUnknown* __stdcall GetObjectContext();
HRESULT __stdcall GetProxyImpl(IUnknown*, REFIID, IUnknown*, IUnknown**);
HRESULT __stdcall ReleaseInContextImpl(IUnknown*, IUnknown*);
template <typename T>
#if _MSC_VER >= 1800
__declspec(no_refcount) inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy)
#else
inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy)
#endif
{
#if _MSC_VER >= 1800
return GetProxyImpl(*reinterpret_cast<IUnknown**>(&ObjectIn), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy));
#else
return GetProxyImpl(*reinterpret_cast<IUnknown**>(&const_cast<T*>(ObjectIn)), __uuidof(T*), ContextCallBack, reinterpret_cast<IUnknown**>(Proxy));
#endif
}
template <typename T>
inline HRESULT ReleaseInContext(T *ObjectIn, IUnknown *ContextCallBack)
{
return ReleaseInContextImpl(ObjectIn, ContextCallBack);
}
template <typename T>
class AgileHelper
{
__abi_IUnknown* _p;
bool _release;
public:
AgileHelper(__abi_IUnknown* p, bool release = true) : _p(p), _release(release)
{
}
AgileHelper(AgileHelper&& other) : _p(other._p), _release(other._release)
{
_other._p = nullptr;
_other._release = true;
}
AgileHelper operator=(AgileHelper&& other)
{
_p = other._p;
_release = other._release;
_other._p = nullptr;
_other._release = true;
return *this;
}
~AgileHelper()
{
if (_release && _p)
{
_p->__abi_Release();
}
}
__declspec(no_refcount) __declspec(no_release_return)
T* operator->()
{
return reinterpret_cast<T*>(_p);
}
__declspec(no_refcount) __declspec(no_release_return)
operator T * ()
{
return reinterpret_cast<T*>(_p);
}
private:
AgileHelper(const AgileHelper&);
AgileHelper operator=(const AgileHelper&);
};
template <typename T>
struct __remove_hat
{
typedef T type;
};
template <typename T>
struct __remove_hat<T*>
{
typedef T type;
};
template <typename T>
struct AgileTypeHelper
{
typename typedef __remove_hat<T>::type type;
typename typedef __remove_hat<T>::type* agileMemberType;
};
} // namespace Details
#pragma warning(push)
#pragma warning(disable: 4451) // Usage of ref class inside this context can lead to invalid marshaling of object across contexts
template <
typename T,
bool TIsNotAgile = (__is_win_class(typename Details::AgileTypeHelper<T>::type) && !__is_winrt_agile(typename Details::AgileTypeHelper<T>::type)) ||
__is_win_interface(typename Details::AgileTypeHelper<T>::type)
>
class Agile
{
static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types");
typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT;
TypeT _object;
::Microsoft::WRL::ComPtr<IUnknown> _contextCallback;
ULONG_PTR _contextToken;
#if _MSC_VER >= 1800
enum class AgileState
{
NonAgilePointer = 0,
AgilePointer = 1,
Unknown = 2
};
AgileState _agileState;
#endif
void CaptureContext()
{
_contextCallback = Details::GetObjectContext();
__abi_ThrowIfFailed(CoGetContextToken(&_contextToken));
}
void SetObject(TypeT object)
{
// Capture context before setting the pointer
// If context capture fails then nothing to cleanup
Release();
if (object != nullptr)
{
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
HRESULT hr = reinterpret_cast<IUnknown*>(object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
// Don't Capture context if object is agile
if (hr != S_OK)
{
#if _MSC_VER >= 1800
_agileState = AgileState::NonAgilePointer;
#endif
CaptureContext();
}
#if _MSC_VER >= 1800
else
{
_agileState = AgileState::AgilePointer;
}
#endif
}
_object = object;
}
public:
Agile() throw() : _object(nullptr), _contextToken(0)
#if _MSC_VER >= 1800
, _agileState(AgileState::Unknown)
#endif
{
}
Agile(nullptr_t) throw() : _object(nullptr), _contextToken(0)
#if _MSC_VER >= 1800
, _agileState(AgileState::Unknown)
#endif
{
}
explicit Agile(TypeT object) throw() : _object(nullptr), _contextToken(0)
#if _MSC_VER >= 1800
, _agileState(AgileState::Unknown)
#endif
{
// Assumes that the source object is from the current context
SetObject(object);
}
Agile(const Agile& object) throw() : _object(nullptr), _contextToken(0)
#if _MSC_VER >= 1800
, _agileState(AgileState::Unknown)
#endif
{
// Get returns pointer valid for current context
SetObject(object.Get());
}
Agile(Agile&& object) throw() : _object(nullptr), _contextToken(0)
#if _MSC_VER >= 1800
, _agileState(AgileState::Unknown)
#endif
{
// Assumes that the source object is from the current context
Swap(object);
}
~Agile() throw()
{
Release();
}
TypeT Get() const
{
// Agile object, no proxy required
#if _MSC_VER >= 1800
if (_agileState == AgileState::AgilePointer || _object == nullptr)
#else
if (_contextToken == 0 || _contextCallback == nullptr || _object == nullptr)
#endif
{
return _object;
}
// Do the check for same context
ULONG_PTR currentContextToken;
__abi_ThrowIfFailed(CoGetContextToken(&currentContextToken));
if (currentContextToken == _contextToken)
{
return _object;
}
#if _MSC_VER >= 1800
// Different context and holding on to a non agile object
// Do the costly work of getting a proxy
TypeT localObject;
__abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject));
if (_agileState == AgileState::Unknown)
#else
// Object is agile if it implements IAgileObject
// GetAddressOf captures the context with out knowing the type of object that it will hold
if (_object != nullptr)
#endif
{
#if _MSC_VER >= 1800
// Object is agile if it implements IAgileObject
// GetAddressOf captures the context with out knowing the type of object that it will hold
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
HRESULT hr = reinterpret_cast<IUnknown*>(localObject)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
#else
::Microsoft::WRL::ComPtr<IAgileObject> checkIfAgile;
HRESULT hr = reinterpret_cast<IUnknown*>(_object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile);
#endif
if (hr == S_OK)
{
auto pThis = const_cast<Agile*>(this);
#if _MSC_VER >= 1800
pThis->_agileState = AgileState::AgilePointer;
#endif
pThis->_contextToken = 0;
pThis->_contextCallback = nullptr;
return _object;
}
#if _MSC_VER >= 1800
else
{
auto pThis = const_cast<Agile*>(this);
pThis->_agileState = AgileState::NonAgilePointer;
}
#endif
}
#if _MSC_VER < 1800
// Different context and holding on to a non agile object
// Do the costly work of getting a proxy
TypeT localObject;
__abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject));
#endif
return localObject;
}
TypeT* GetAddressOf() throw()
{
Release();
CaptureContext();
return &_object;
}
TypeT* GetAddressOfForInOut() throw()
{
CaptureContext();
return &_object;
}
TypeT operator->() const throw()
{
return Get();
}
Agile& operator=(nullptr_t) throw()
{
Release();
return *this;
}
Agile& operator=(TypeT object) throw()
{
Agile(object).Swap(*this);
return *this;
}
Agile& operator=(Agile object) throw()
{
// parameter is by copy which gets pointer valid for current context
object.Swap(*this);
return *this;
}
#if _MSC_VER < 1800
Agile& operator=(IUnknown* lp) throw()
{
// bump ref count
::Microsoft::WRL::ComPtr<IUnknown> spObject(lp);
// put it into Platform Object
Platform::Object object;
*(IUnknown**)(&object) = spObject.Detach();
SetObject(object);
return *this;
}
#endif
void Swap(Agile& object)
{
std::swap(_object, object._object);
std::swap(_contextCallback, object._contextCallback);
std::swap(_contextToken, object._contextToken);
#if _MSC_VER >= 1800
std::swap(_agileState, object._agileState);
#endif
}
// Release the interface and set to NULL
void Release() throw()
{
if (_object)
{
// Cast to IInspectable (no QI)
IUnknown* pObject = *(IUnknown**)(&_object);
// Set * to null without release
*(IUnknown**)(&_object) = nullptr;
ULONG_PTR currentContextToken;
__abi_ThrowIfFailed(CoGetContextToken(&currentContextToken));
if (_contextToken == 0 || _contextCallback == nullptr || _contextToken == currentContextToken)
{
pObject->Release();
}
else
{
Details::ReleaseInContext(pObject, _contextCallback.Get());
}
_contextCallback = nullptr;
_contextToken = 0;
#if _MSC_VER >= 1800
_agileState = AgileState::Unknown;
#endif
}
}
bool operator==(nullptr_t) const throw()
{
return _object == nullptr;
}
bool operator==(const Agile& other) const throw()
{
return _object == other._object && _contextToken == other._contextToken;
}
bool operator<(const Agile& other) const throw()
{
if (reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object))
{
return true;
}
return _object == other._object && _contextToken < other._contextToken;
}
};
template <typename T>
class Agile<T, false>
{
static_assert(__is_win_class(typename Details::AgileTypeHelper<T>::type) || __is_win_interface(typename Details::AgileTypeHelper<T>::type), "Agile can only be used with ref class or interface class types");
typename typedef Details::AgileTypeHelper<T>::agileMemberType TypeT;
TypeT _object;
public:
Agile() throw() : _object(nullptr)
{
}
Agile(nullptr_t) throw() : _object(nullptr)
{
}
explicit Agile(TypeT object) throw() : _object(object)
{
}
Agile(const Agile& object) throw() : _object(object._object)
{
}
Agile(Agile&& object) throw() : _object(nullptr)
{
Swap(object);
}
~Agile() throw()
{
Release();
}
TypeT Get() const
{
return _object;
}
TypeT* GetAddressOf() throw()
{
Release();
return &_object;
}
TypeT* GetAddressOfForInOut() throw()
{
return &_object;
}
TypeT operator->() const throw()
{
return Get();
}
Agile& operator=(nullptr_t) throw()
{
Release();
return *this;
}
Agile& operator=(TypeT object) throw()
{
if (_object != object)
{
_object = object;
}
return *this;
}
Agile& operator=(Agile object) throw()
{
object.Swap(*this);
return *this;
}
#if _MSC_VER < 1800
Agile& operator=(IUnknown* lp) throw()
{
Release();
// bump ref count
::Microsoft::WRL::ComPtr<IUnknown> spObject(lp);
// put it into Platform Object
Platform::Object object;
*(IUnknown**)(&object) = spObject.Detach();
_object = object;
return *this;
}
#endif
// Release the interface and set to NULL
void Release() throw()
{
_object = nullptr;
}
void Swap(Agile& object)
{
std::swap(_object, object._object);
}
bool operator==(nullptr_t) const throw()
{
return _object == nullptr;
}
bool operator==(const Agile& other) const throw()
{
return _object == other._object;
}
bool operator<(const Agile& other) const throw()
{
return reinterpret_cast<void*>(_object) < reinterpret_cast<void*>(other._object);
}
};
#pragma warning(pop)
template<class U>
bool operator==(nullptr_t, const Agile<U>& a) throw()
{
return a == nullptr;
}
template<class U>
bool operator!=(const Agile<U>& a, nullptr_t) throw()
{
return !(a == nullptr);
}
template<class U>
bool operator!=(nullptr_t, const Agile<U>& a) throw()
{
return !(a == nullptr);
}
template<class U>
bool operator!=(const Agile<U>& a, const Agile<U>& b) throw()
{
return !(a == b);
}
#endif // _PLATFORM_AGILE_H_
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -161,7 +161,7 @@ __kernel void matchTemplate_Naive_CCORR(__global const uchar * srcptr, int src_s ...@@ -161,7 +161,7 @@ __kernel void matchTemplate_Naive_CCORR(__global const uchar * srcptr, int src_s
for (int j = 0; j < template_cols; ++j) for (int j = 0; j < template_cols; ++j)
{ {
T temp = (T)(template[j]); T temp = (T)(template[j]);
T src = *(__global const T*)(srcptr + ind + j*(int)sizeof(T1)); T src = vload4(0, (__global const T1*)(srcptr + ind + j*(int)sizeof(T1)));
sum = mad(convertToWT(src), convertToWT(temp), sum); sum = mad(convertToWT(src), convertToWT(temp), sum);
......
...@@ -341,12 +341,9 @@ pyrUp_( const Mat& _src, Mat& _dst, int) ...@@ -341,12 +341,9 @@ pyrUp_( const Mat& _src, Mat& _dst, int)
for( int y = 0; y < ssize.height; y++ ) for( int y = 0; y < ssize.height; y++ )
{ {
T* dst0 = _dst.ptr<T>(y*2); T* dst0 = _dst.ptr<T>(y*2);
T* dst1 = _dst.ptr<T>(y*2+1); T* dst1 = _dst.ptr<T>(std::min(y*2+1, dsize.height-1));
WT *row0, *row1, *row2; WT *row0, *row1, *row2;
if( y*2+1 >= dsize.height )
dst1 = dst0;
// fill the ring buffer (horizontal convolution and decimation) // fill the ring buffer (horizontal convolution and decimation)
for( ; sy <= y + 1; sy++ ) for( ; sy <= y + 1; sy++ )
{ {
......
...@@ -47,12 +47,21 @@ ...@@ -47,12 +47,21 @@
Originaly licensed under The Code Project Open License (CPOL) 1.02: Originaly licensed under The Code Project Open License (CPOL) 1.02:
http://www.codeproject.com/info/cpol10.aspx http://www.codeproject.com/info/cpol10.aspx
*/ */
//require Windows 8 for some of the formats defined otherwise could baseline on lower version
#if WINVER < _WIN32_WINNT_WIN7
#undef WINVER
#define WINVER _WIN32_WINNT_WIN7
#endif
#if defined _MSC_VER && _MSC_VER >= 1600
#define HAVE_CONCURRENCY
#endif
#include <windows.h> #include <windows.h>
#include <guiddef.h> #include <guiddef.h>
#include <mfidl.h> #include <mfidl.h>
#include <Mfapi.h> #include <Mfapi.h>
#include <mfplay.h> #include <mfplay.h>
#include <mfobjects.h> #include <mfobjects.h>
#include <tchar.h>
#include <strsafe.h> #include <strsafe.h>
#include <Mfreadwrite.h> #include <Mfreadwrite.h>
#include <new> #include <new>
...@@ -71,13 +80,11 @@ ...@@ -71,13 +80,11 @@
#pragma comment(lib, "Mfreadwrite") #pragma comment(lib, "Mfreadwrite")
#pragma comment(lib, "MinCore_Downlevel") #pragma comment(lib, "MinCore_Downlevel")
// for ComPtr usage
#include <wrl/client.h>
using namespace Microsoft::WRL;
#include <mferror.h> #include <mferror.h>
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
// for ComPtr usage
#include <wrl/client.h>
#ifdef __cplusplus_winrt #ifdef __cplusplus_winrt
#include <agile.h> #include <agile.h>
#include <vccorlib.h> #include <vccorlib.h>
...@@ -89,10 +96,169 @@ using namespace Microsoft::WRL; ...@@ -89,10 +96,169 @@ using namespace Microsoft::WRL;
#include <wrl\wrappers\corewrappers.h> #include <wrl\wrappers\corewrappers.h>
#include <windows.media.capture.h> #include <windows.media.capture.h>
#include <windows.devices.enumeration.h> #include <windows.devices.enumeration.h>
#ifdef HAVE_CONCURRENCY
#include <concrt.h> #include <concrt.h>
#include <ppltasks.h> #ifndef __cplusplus_winrt
__declspec(noreturn) void __stdcall __abi_WinRTraiseException(long);
inline void __abi_ThrowIfFailed(long __hrArg)
{
if (__hrArg < 0)
{
__abi_WinRTraiseException(__hrArg);
}
}
using namespace Microsoft::WRL::Wrappers; struct Guid
{
public:
Guid();
Guid(__rcGUID_t);
operator ::__rcGUID_t();
bool Equals(Guid __guidArg);
bool Equals(__rcGUID_t __guidArg);
Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg);
Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8* __dArg);
private:
unsigned long __a;
unsigned short __b;
unsigned short __c;
unsigned char __d;
unsigned char __e;
unsigned char __f;
unsigned char __g;
unsigned char __h;
unsigned char __i;
unsigned char __j;
unsigned char __k;
};
static_assert(sizeof(Guid) == sizeof(::_GUID), "Incorect size for Guid");
static_assert(sizeof(__rcGUID_t) == sizeof(::_GUID), "Incorect size for __rcGUID_t");
////////////////////////////////////////////////////////////////////////////////
inline Guid::Guid() : __a(0), __b(0), __c(0), __d(0), __e(0), __f(0), __g(0), __h(0), __i(0), __j(0), __k(0)
{
}
inline Guid::Guid(__rcGUID_t __guid) :
__a(reinterpret_cast<const __s_GUID&>(__guid).Data1),
__b(reinterpret_cast<const __s_GUID&>(__guid).Data2),
__c(reinterpret_cast<const __s_GUID&>(__guid).Data3),
__d(reinterpret_cast<const __s_GUID&>(__guid).Data4[0]),
__e(reinterpret_cast<const __s_GUID&>(__guid).Data4[1]),
__f(reinterpret_cast<const __s_GUID&>(__guid).Data4[2]),
__g(reinterpret_cast<const __s_GUID&>(__guid).Data4[3]),
__h(reinterpret_cast<const __s_GUID&>(__guid).Data4[4]),
__i(reinterpret_cast<const __s_GUID&>(__guid).Data4[5]),
__j(reinterpret_cast<const __s_GUID&>(__guid).Data4[6]),
__k(reinterpret_cast<const __s_GUID&>(__guid).Data4[7])
{
}
inline Guid::operator ::__rcGUID_t()
{
return reinterpret_cast<__rcGUID_t>(*this);
}
inline bool Guid::Equals(Guid __guidArg)
{
return *this == __guidArg;
}
inline bool Guid::Equals(__rcGUID_t __guidArg)
{
return *this == static_cast< Guid>(__guidArg);
}
inline bool operator==(Guid __aArg, Guid __bArg)
{
auto __a = reinterpret_cast<unsigned long*>(&__aArg);
auto __b = reinterpret_cast<unsigned long*>(&__bArg);
return (__a[0] == __b[0] && __a[1] == __b[1] && __a[2] == __b[2] && __a[3] == __b[3]);
}
inline bool operator!=(Guid __aArg, Guid __bArg)
{
return !(__aArg == __bArg);
}
inline bool operator<(Guid __aArg, Guid __bArg)
{
auto __a = reinterpret_cast<unsigned long*>(&__aArg);
auto __b = reinterpret_cast<unsigned long*>(&__bArg);
if (__a[0] != __b[0])
{
return __a[0] < __b[0];
}
if (__a[1] != __b[1])
{
return __a[1] < __b[1];
}
if (__a[2] != __b[2])
{
return __a[2] < __b[2];
}
if (__a[3] != __b[3])
{
return __a[3] < __b[3];
}
return false;
}
inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg) :
__a(__aArg), __b(__bArg), __c(__cArg), __d(__dArg), __e(__eArg), __f(__fArg), __g(__gArg), __h(__hArg), __i(__iArg), __j(__jArg), __k(__kArg)
{
}
inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8 __dArg[8]) :
__a(__aArg), __b(__bArg), __c(__cArg)
{
__d = __dArg[0];
__e = __dArg[1];
__f = __dArg[2];
__g = __dArg[3];
__h = __dArg[4];
__i = __dArg[5];
__j = __dArg[6];
__k = __dArg[7];
}
__declspec(selectany) Guid __winrt_GUID_NULL(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
//
//// Don't want to define the real IUnknown from unknown.h here. That would means if the user has
//// any broken code that uses it, compile errors will take the form of e.g.:
//// predefined C++ WinRT types (compiler internal)(41) : see declaration of 'IUnknown::QueryInterface'
//// This is not helpful. If they use IUnknown, we still need to point them to the actual unknown.h so
//// that they can see the original definition.
////
//// For WinRT, we'll instead have a parallel COM interface hierarchy for basic interfaces starting with _.
//// The type mismatch is not an issue. COM passes types through GUID / void* combos - the original type
//// doesn't come into play unless the user static_casts an implementation type to one of these, but
//// the WinRT implementation types are hidden.
__interface __declspec(uuid("00000000-0000-0000-C000-000000000046")) __abi_IUnknown
{
public:
virtual long __stdcall __abi_QueryInterface(Guid&, void**) = 0;
virtual unsigned long __stdcall __abi_AddRef() = 0;
virtual unsigned long __stdcall __abi_Release() = 0;
};
#endif
#include "ppltasks_winrt.h"
#endif
#else
#include <atlbase.h>
#endif #endif
struct IMFMediaType; struct IMFMediaType;
...@@ -114,18 +280,23 @@ template <class T> void SafeRelease(T **ppT) ...@@ -114,18 +280,23 @@ template <class T> void SafeRelease(T **ppT)
} }
} }
/// Class for printing info into consol #ifdef _DEBUG
class DebugPrintOut /// Class for printing info into console
class DPO
{ {
public: public:
~DebugPrintOut(void); ~DPO(void);
static DebugPrintOut& getInstance(); static DPO& getInstance();
void printOut(const wchar_t *format, ...); void printOut(const wchar_t *format, ...);
void setVerbose(bool state); void setVerbose(bool state);
bool verbose; bool verbose;
private: private:
DebugPrintOut(void); DPO(void);
}; };
#define DebugPrintOut(...) DPO::getInstance().printOut(__VA_ARGS__)
#else
#define DebugPrintOut(...) void()
#endif
#include "cap_msmf.hpp" #include "cap_msmf.hpp"
...@@ -227,7 +398,9 @@ protected: ...@@ -227,7 +398,9 @@ protected:
RawImage *ig_RIFirst; RawImage *ig_RIFirst;
RawImage *ig_RISecond; RawImage *ig_RISecond;
RawImage *ig_RIOut; RawImage *ig_RIOut;
}; private:
ImageGrabberCallback& operator=(const ImageGrabberCallback&); // Declared to fix compilation warning.
};
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
extern const __declspec(selectany) WCHAR RuntimeClass_CV_ImageGrabberWinRT[] = L"cv.ImageGrabberWinRT"; extern const __declspec(selectany) WCHAR RuntimeClass_CV_ImageGrabberWinRT[] = L"cv.ImageGrabberWinRT";
...@@ -271,7 +444,7 @@ class ImageGrabber : public ImageGrabberCallback ...@@ -271,7 +444,7 @@ class ImageGrabber : public ImageGrabberCallback
{ {
public: public:
~ImageGrabber(void); ~ImageGrabber(void);
HRESULT initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat); HRESULT initImageGrabber(IMFMediaSource *pSource);
HRESULT startGrabbing(void); HRESULT startGrabbing(void);
void stopGrabbing(); void stopGrabbing();
// IUnknown methods // IUnknown methods
...@@ -292,6 +465,8 @@ private: ...@@ -292,6 +465,8 @@ private:
HRESULT AddSourceNode(IMFTopology *pTopology, IMFMediaSource *pSource, HRESULT AddSourceNode(IMFTopology *pTopology, IMFMediaSource *pSource,
IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode); IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode);
HRESULT AddOutputNode(IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode); HRESULT AddOutputNode(IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode);
ImageGrabber& operator=(const ImageGrabber&); // Declared to fix comiplation error.
}; };
/// Class for controlling of thread of the grabbing raw data from video device /// Class for controlling of thread of the grabbing raw data from video device
...@@ -373,8 +548,9 @@ public: ...@@ -373,8 +548,9 @@ public:
void waitForDevice() void waitForDevice()
{ {
if (vd_pAction) { if (vd_pAction) {
HRESULT hr; #ifdef HAVE_CONCURRENCY
DO_ACTION_SYNCHRONOUSLY(hr, vd_pAction, GET_CURRENT_CONTEXT); CREATE_TASK DEFINE_RET_TYPE(void)(vd_pAction).wait();
#endif
vd_pAction = nullptr; vd_pAction = nullptr;
} }
} }
...@@ -385,6 +561,7 @@ public: ...@@ -385,6 +561,7 @@ public:
int getCountFormats(); int getCountFormats();
unsigned int getWidth(); unsigned int getWidth();
unsigned int getHeight(); unsigned int getHeight();
unsigned int getFrameRate() const;
MediaType getFormat(unsigned int id); MediaType getFormat(unsigned int id);
bool setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate = 0); bool setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate = 0);
bool setupDevice(unsigned int id); bool setupDevice(unsigned int id);
...@@ -406,6 +583,7 @@ private: ...@@ -406,6 +583,7 @@ private:
CamParametrs vd_PrevParametrs; CamParametrs vd_PrevParametrs;
unsigned int vd_Width; unsigned int vd_Width;
unsigned int vd_Height; unsigned int vd_Height;
unsigned int vd_FrameRate;
unsigned int vd_CurrentNumber; unsigned int vd_CurrentNumber;
bool vd_IsSetuped; bool vd_IsSetuped;
std::map<UINT64, FrameRateMap> vd_CaptureFormats; std::map<UINT64, FrameRateMap> vd_CaptureFormats;
...@@ -413,10 +591,12 @@ private: ...@@ -413,10 +591,12 @@ private:
IMFMediaSource *vd_pSource; IMFMediaSource *vd_pSource;
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
MAKE_WRL_AGILE_REF(_MediaCapture) vd_pMedCap; MAKE_WRL_AGILE_REF(_MediaCapture) vd_pMedCap;
IMedCapFailHandler* vd_pMedCapFail; EventRegistrationToken vd_cookie;
ImageGrabberWinRT *vd_pImGr; ImageGrabberWinRT *vd_pImGr;
MAKE_WRL_REF(_AsyncAction) vd_pAction; MAKE_WRL_REF(_AsyncAction) vd_pAction;
#ifdef HAVE_CONCURRENCY
Concurrency::critical_section vd_lock; Concurrency::critical_section vd_lock;
#endif
#endif #endif
emergensyStopEventCallback vd_func; emergensyStopEventCallback vd_func;
void *vd_userData; void *vd_userData;
...@@ -428,7 +608,9 @@ private: ...@@ -428,7 +608,9 @@ private:
HRESULT enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource); HRESULT enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource);
long setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned long dwFormatIndex, MAKE_WRL_REF(_AsyncAction)* pAction); long setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned long dwFormatIndex, MAKE_WRL_REF(_AsyncAction)* pAction);
long resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice); long resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice);
long checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice); #ifdef HAVE_CONCURRENCY
long checkDevice(_DeviceClass devClass, DEFINE_TASK<void>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice);
#endif
#else #else
long resetDevice(IMFActivate *pActivate); long resetDevice(IMFActivate *pActivate);
long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice); long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice);
...@@ -445,8 +627,9 @@ public: ...@@ -445,8 +627,9 @@ public:
long initDevices(_DeviceClass devClass); long initDevices(_DeviceClass devClass);
void waitInit() { void waitInit() {
if (vds_enumTask) { if (vds_enumTask) {
HRESULT hr; #ifdef HAVE_CONCURRENCY
DO_ACTION_SYNCHRONOUSLY(hr, vds_enumTask, GET_CURRENT_CONTEXT); CREATE_TASK DEFINE_RET_TYPE(void)(vds_enumTask).wait();
#endif
vds_enumTask = nullptr; vds_enumTask = nullptr;
} }
} }
...@@ -502,6 +685,8 @@ public: ...@@ -502,6 +685,8 @@ public:
unsigned int getWidth(int deviceID); unsigned int getWidth(int deviceID);
// Getting height of image, which is getting from videodevice with deviceID // Getting height of image, which is getting from videodevice with deviceID
unsigned int getHeight(int deviceID); unsigned int getHeight(int deviceID);
// Getting frame rate, which is getting from videodevice with deviceID
unsigned int getFrameRate(int deviceID) const;
// Getting name of videodevice with deviceID // Getting name of videodevice with deviceID
wchar_t *getNameVideoDevice(int deviceID); wchar_t *getNameVideoDevice(int deviceID);
// Getting interface MediaSource for Media Foundation from videodevice with deviceID // Getting interface MediaSource for Media Foundation from videodevice with deviceID
...@@ -516,8 +701,10 @@ public: ...@@ -516,8 +701,10 @@ public:
bool isDeviceMediaSource(int deviceID); bool isDeviceMediaSource(int deviceID);
// Checking of using Raw Data of pixels from videodevice with deviceID // Checking of using Raw Data of pixels from videodevice with deviceID
bool isDeviceRawDataSource(int deviceID); bool isDeviceRawDataSource(int deviceID);
#ifdef _DEBUG
// Setting of the state of outprinting info in console // Setting of the state of outprinting info in console
static void setVerbose(bool state); static void setVerbose(bool state);
#endif
// Initialization of video device with deviceID by media type with id // Initialization of video device with deviceID by media type with id
bool setupDevice(int deviceID, unsigned int id = 0); bool setupDevice(int deviceID, unsigned int id = 0);
// Initialization of video device with deviceID by wisth w, height h and fps idealFramerate // Initialization of video device with deviceID by wisth w, height h and fps idealFramerate
...@@ -536,21 +723,22 @@ private: ...@@ -536,21 +723,22 @@ private:
void updateListOfDevices(); void updateListOfDevices();
}; };
DebugPrintOut::DebugPrintOut(void):verbose(true) #ifdef _DEBUG
DPO::DPO(void):verbose(true)
{ {
} }
DebugPrintOut::~DebugPrintOut(void) DPO::~DPO(void)
{ {
} }
DebugPrintOut& DebugPrintOut::getInstance() DPO& DPO::getInstance()
{ {
static DebugPrintOut instance; static DPO instance;
return instance; return instance;
} }
void DebugPrintOut::printOut(const wchar_t *format, ...) void DPO::printOut(const wchar_t *format, ...)
{ {
if(verbose) if(verbose)
{ {
...@@ -558,6 +746,14 @@ void DebugPrintOut::printOut(const wchar_t *format, ...) ...@@ -558,6 +746,14 @@ void DebugPrintOut::printOut(const wchar_t *format, ...)
wchar_t *p = NULL; wchar_t *p = NULL;
va_list args; va_list args;
va_start(args, format); va_start(args, format);
if( ::IsDebuggerPresent() )
{
WCHAR szMsg[512];
::StringCchVPrintfW(szMsg, sizeof(szMsg)/sizeof(szMsg[0]), format, args);
::OutputDebugStringW(szMsg);
}
else
{
if(wcscmp(format, L"%i")) if(wcscmp(format, L"%i"))
{ {
i = va_arg (args, int); i = va_arg (args, int);
...@@ -567,14 +763,16 @@ void DebugPrintOut::printOut(const wchar_t *format, ...) ...@@ -567,14 +763,16 @@ void DebugPrintOut::printOut(const wchar_t *format, ...)
p = va_arg (args, wchar_t *); p = va_arg (args, wchar_t *);
} }
wprintf(format, i,p); wprintf(format, i,p);
}
va_end (args); va_end (args);
} }
} }
void DebugPrintOut::setVerbose(bool state) void DPO::setVerbose(bool state)
{ {
verbose = state; verbose = state;
} }
#endif
LPCWSTR GetGUIDNameConstNew(const GUID& guid); LPCWSTR GetGUIDNameConstNew(const GUID& guid);
HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz); HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz);
...@@ -650,7 +848,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType ...@@ -650,7 +848,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
hr = GetGUIDNameNew(*var.puuid, &pGuidValName); hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
out.MF_MT_AM_FORMAT_TYPE = MF_MT_AM_FORMAT_TYPE; out.MF_MT_AM_FORMAT_TYPE = *var.puuid;
out.pMF_MT_AM_FORMAT_TYPEName = pGuidValName; out.pMF_MT_AM_FORMAT_TYPEName = pGuidValName;
pGuidValName = NULL; pGuidValName = NULL;
} }
...@@ -660,7 +858,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType ...@@ -660,7 +858,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
hr = GetGUIDNameNew(*var.puuid, &pGuidValName); hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
out.MF_MT_MAJOR_TYPE = MF_MT_MAJOR_TYPE; out.MF_MT_MAJOR_TYPE = *var.puuid;
out.pMF_MT_MAJOR_TYPEName = pGuidValName; out.pMF_MT_MAJOR_TYPEName = pGuidValName;
pGuidValName = NULL; pGuidValName = NULL;
} }
...@@ -670,7 +868,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType ...@@ -670,7 +868,7 @@ HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType
hr = GetGUIDNameNew(*var.puuid, &pGuidValName); hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
out.MF_MT_SUBTYPE = MF_MT_SUBTYPE; out.MF_MT_SUBTYPE = *var.puuid;
out.pMF_MT_SUBTYPEName = pGuidValName; out.pMF_MT_SUBTYPEName = pGuidValName;
pGuidValName = NULL; pGuidValName = NULL;
} }
...@@ -963,9 +1161,8 @@ FormatReader::FormatReader(void) ...@@ -963,9 +1161,8 @@ FormatReader::FormatReader(void)
MediaType FormatReader::Read(IMFMediaType *pType) MediaType FormatReader::Read(IMFMediaType *pType)
{ {
UINT32 count = 0; UINT32 count = 0;
HRESULT hr = S_OK;
MediaType out; MediaType out;
hr = pType->LockStore(); HRESULT hr = pType->LockStore();
if (FAILED(hr)) if (FAILED(hr))
{ {
return out; return out;
...@@ -1032,9 +1229,8 @@ ImageGrabber::~ImageGrabber(void) ...@@ -1032,9 +1229,8 @@ ImageGrabber::~ImageGrabber(void)
SafeRelease(&ig_pSession); SafeRelease(&ig_pSession);
SafeRelease(&ig_pTopology); SafeRelease(&ig_pTopology);
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroying instance of the ImageGrabber class\n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroying instance of the ImageGrabber class\n", ig_DeviceID);
} }
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
...@@ -1063,9 +1259,7 @@ ImageGrabberWinRT::~ImageGrabberWinRT(void) ...@@ -1063,9 +1259,7 @@ ImageGrabberWinRT::~ImageGrabberWinRT(void)
CloseHandle(ig_hFrameGrabbed); CloseHandle(ig_hFrameGrabbed);
} }
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE: Destroying instance of the ImageGrabberWinRT class\n");
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Destroying instance of the ImageGrabberWinRT class\n");
} }
HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource, HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
...@@ -1082,7 +1276,7 @@ HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource, ...@@ -1082,7 +1276,7 @@ HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
GET_WRL_OBJ_FROM_OBJ(_VideoEncodingProperties, pVidProps, pMedEncProps, hr); GET_WRL_OBJ_FROM_OBJ(_VideoEncodingProperties, pVidProps, pMedEncProps, hr);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType); hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
MediaType MT = FormatReader::Read(pType.Get()); MediaType MT = FormatReader::Read(pType.Get());
...@@ -1113,13 +1307,17 @@ HRESULT ImageGrabberWinRT::stopGrabbing(MAKE_WRL_REF(_AsyncAction)* action) ...@@ -1113,13 +1307,17 @@ HRESULT ImageGrabberWinRT::stopGrabbing(MAKE_WRL_REF(_AsyncAction)* action)
MAKE_WRL_REF(_AsyncAction) pAction; MAKE_WRL_REF(_AsyncAction) pAction;
WRL_METHOD_BASE(imedPrevCap, StopPreviewAsync, pAction, hr) WRL_METHOD_BASE(imedPrevCap, StopPreviewAsync, pAction, hr)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
SAVE_CURRENT_CONTEXT(context); #ifdef HAVE_CONCURRENCY
*action = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this) DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
HRESULT hr; *action = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, this)
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context); HRESULT hr = S_OK;
_task.wait();
SafeRelease(&ig_pMediaSink); SafeRelease(&ig_pMediaSink);
SetEvent(ig_hFinish); SetEvent(ig_hFinish);
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#else
*action = nullptr;
#endif
} }
} }
return hr; return hr;
...@@ -1180,21 +1378,19 @@ HRESULT ImageGrabberWinRT::CreateInstance(ImageGrabberWinRT **ppIG, bool synchro ...@@ -1180,21 +1378,19 @@ HRESULT ImageGrabberWinRT::CreateInstance(ImageGrabberWinRT **ppIG, bool synchro
{ {
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE: Creating instance of ImageGrabberWinRT\n");
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Creating instance of ImageGrabberWinRT\n");
return S_OK; return S_OK;
} }
#endif #endif
HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat) HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource)
{ {
ComPtr<IMFActivate> pSinkActivate = NULL; _ComPtr<IMFActivate> pSinkActivate = NULL;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
ComPtr<IMFPresentationDescriptor> pPD = NULL; _ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL; _ComPtr<IMFStreamDescriptor> pSD = NULL;
ComPtr<IMFMediaTypeHandler> pHandler = NULL; _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
ComPtr<IMFMediaType> pCurrentType = NULL; _ComPtr<IMFMediaType> pCurrentType = NULL;
HRESULT hr = S_OK;
MediaType MT; MediaType MT;
// Clean up. // Clean up.
if (ig_pSession) if (ig_pSession)
...@@ -1204,7 +1400,7 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat ...@@ -1204,7 +1400,7 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat
SafeRelease(&ig_pSession); SafeRelease(&ig_pSession);
SafeRelease(&ig_pTopology); SafeRelease(&ig_pTopology);
ig_pSource = pSource; ig_pSource = pSource;
hr = pSource->CreatePresentationDescriptor(&pPD); HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
if (FAILED(hr)) if (FAILED(hr))
{ {
goto err; goto err;
...@@ -1232,25 +1428,16 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat ...@@ -1232,25 +1428,16 @@ HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat
MT = FormatReader::Read(pCurrentType.Get()); MT = FormatReader::Read(pCurrentType.Get());
} }
err: err:
unsigned int sizeRawImage = 0; CHECK_HR(hr);
if(VideoFormat == MFVideoFormat_RGB24) CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, MT.MF_MT_SAMPLE_SIZE));
{ CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, MT.MF_MT_SAMPLE_SIZE));
sizeRawImage = MT.MF_MT_FRAME_SIZE * 3;
}
else if(VideoFormat == MFVideoFormat_RGB32)
{
sizeRawImage = MT.MF_MT_FRAME_SIZE * 4;
}
//sizeRawImage = MT.MF_MT_SAMPLE_SIZE;
CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, sizeRawImage));
CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, sizeRawImage));
ig_RIOut = ig_RISecond; ig_RIOut = ig_RISecond;
// Configure the media type that the Sample Grabber will receive. // Configure the media type that the Sample Grabber will receive.
// Setting the major and subtype is usually enough for the topology loader // Setting the major and subtype is usually enough for the topology loader
// to resolve the topology. // to resolve the topology.
CHECK_HR(hr = MFCreateMediaType(pType.GetAddressOf())); CHECK_HR(hr = MFCreateMediaType(pType.GetAddressOf()));
CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MT.MF_MT_MAJOR_TYPE));
CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, VideoFormat)); CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, MT.MF_MT_SUBTYPE));
// Create the sample grabber sink. // Create the sample grabber sink.
CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType.Get(), this, pSinkActivate.GetAddressOf())); CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType.Get(), this, pSinkActivate.GetAddressOf()));
// To run as fast as possible, set this attribute (requires Windows 7): // To run as fast as possible, set this attribute (requires Windows 7):
...@@ -1277,19 +1464,16 @@ void ImageGrabber::stopGrabbing() ...@@ -1277,19 +1464,16 @@ void ImageGrabber::stopGrabbing()
{ {
if(ig_pSession) if(ig_pSession)
ig_pSession->Stop(); ig_pSession->Stop();
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
} }
HRESULT ImageGrabber::startGrabbing(void) HRESULT ImageGrabber::startGrabbing(void)
{ {
HRESULT hr = S_OK; _ComPtr<IMFMediaEvent> pEvent = NULL;
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
ComPtr<IMFMediaEvent> pEvent = NULL;
PROPVARIANT var; PROPVARIANT var;
PropVariantInit(&var); PropVariantInit(&var);
hr = ig_pSession->SetTopology(0, ig_pTopology); HRESULT hr = ig_pSession->SetTopology(0, ig_pTopology);
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID);
hr = ig_pSession->Start(&GUID_NULL, &var); hr = ig_pSession->Start(&GUID_NULL, &var);
for(;;) for(;;)
{ {
...@@ -1316,28 +1500,28 @@ HRESULT ImageGrabber::startGrabbing(void) ...@@ -1316,28 +1500,28 @@ HRESULT ImageGrabber::startGrabbing(void)
} }
if (met == MESessionEnded) if (met == MESessionEnded)
{ {
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded \n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded\n", ig_DeviceID);
ig_pSession->Stop(); ig_pSession->Stop();
break; break;
} }
if (met == MESessionStopped) if (met == MESessionStopped)
{ {
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID);
break; break;
} }
if (met == MEVideoCaptureDeviceRemoved) if (met == MEVideoCaptureDeviceRemoved)
{ {
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
break; break;
} }
if ((met == MEError) || (met == MENonFatalError)) if ((met == MEError) || (met == MENonFatalError))
{ {
pEvent->GetStatus(&hrStatus); pEvent->GetStatus(&hrStatus);
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
break; break;
} }
} }
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
done: done:
SetEvent(ig_hFinish); SetEvent(ig_hFinish);
...@@ -1356,11 +1540,11 @@ void ImageGrabberCallback::resumeGrabbing() ...@@ -1356,11 +1540,11 @@ void ImageGrabberCallback::resumeGrabbing()
HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo) HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo)
{ {
IMFTopology* pTopology = NULL; IMFTopology* pTopology = NULL;
ComPtr<IMFPresentationDescriptor> pPD = NULL; _ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL; _ComPtr<IMFStreamDescriptor> pSD = NULL;
ComPtr<IMFMediaTypeHandler> pHandler = NULL; _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
ComPtr<IMFTopologyNode> pNode1 = NULL; _ComPtr<IMFTopologyNode> pNode1 = NULL;
ComPtr<IMFTopologyNode> pNode2 = NULL; _ComPtr<IMFTopologyNode> pNode2 = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
DWORD cStreams = 0; DWORD cStreams = 0;
CHECK_HR(hr = MFCreateTopology(&pTopology)); CHECK_HR(hr = MFCreateTopology(&pTopology));
...@@ -1400,7 +1584,7 @@ HRESULT ImageGrabber::AddSourceNode( ...@@ -1400,7 +1584,7 @@ HRESULT ImageGrabber::AddSourceNode(
IMFStreamDescriptor *pSD, // Stream descriptor. IMFStreamDescriptor *pSD, // Stream descriptor.
IMFTopologyNode **ppNode) // Receives the node pointer. IMFTopologyNode **ppNode) // Receives the node pointer.
{ {
ComPtr<IMFTopologyNode> pNode = NULL; _ComPtr<IMFTopologyNode> pNode = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf())); CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf()));
CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource)); CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
...@@ -1421,7 +1605,7 @@ HRESULT ImageGrabber::AddOutputNode( ...@@ -1421,7 +1605,7 @@ HRESULT ImageGrabber::AddOutputNode(
DWORD dwId, // Identifier of the stream sink. DWORD dwId, // Identifier of the stream sink.
IMFTopologyNode **ppNode) // Receives the node pointer. IMFTopologyNode **ppNode) // Receives the node pointer.
{ {
ComPtr<IMFTopologyNode> pNode = NULL; _ComPtr<IMFTopologyNode> pNode = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, pNode.GetAddressOf())); CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, pNode.GetAddressOf()));
CHECK_HR(hr = pNode->SetObject(pActivate)); CHECK_HR(hr = pNode->SetObject(pActivate));
...@@ -1443,8 +1627,7 @@ HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID, ...@@ -1443,8 +1627,7 @@ HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID,
{ {
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
return S_OK; return S_OK;
} }
...@@ -1537,7 +1720,7 @@ STDMETHODIMP ImageGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, D ...@@ -1537,7 +1720,7 @@ STDMETHODIMP ImageGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, D
DWORD status = WaitForMultipleObjects(2, tmp, FALSE, INFINITE); DWORD status = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
if (status == WAIT_OBJECT_0) if (status == WAIT_OBJECT_0)
{ {
printf("OnProcessFrame called after ig_hFinish event\n"); DebugPrintOut(L"OnProcessFrame called after ig_hFinish event\n");
return S_OK; return S_OK;
} }
...@@ -1584,15 +1767,14 @@ DWORD WINAPI MainThreadFunction( LPVOID lpParam ) ...@@ -1584,15 +1767,14 @@ DWORD WINAPI MainThreadFunction( LPVOID lpParam )
HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious) HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
*ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID, synchronious); *ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID, synchronious);
if (ppIGT == NULL) if (ppIGT == NULL)
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
else else
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID);
return S_OK; return S_OK;
} }
...@@ -1601,24 +1783,23 @@ ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int dev ...@@ -1601,24 +1783,23 @@ ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int dev
igt_Handle(NULL), igt_Handle(NULL),
igt_stop(false) igt_stop(false)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID, synchronious); HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID, synchronious);
igt_DeviceID = deviceID; igt_DeviceID = deviceID;
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
hr = igt_pImageGrabber->initImageGrabber(pSource, MFVideoFormat_RGB24); hr = igt_pImageGrabber->initImageGrabber(pSource);
if(!SUCCEEDED(hr)) if(!SUCCEEDED(hr))
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID);
} }
else else
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID);
} }
} }
else else
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with creation of the instance of the ImageGrabber class\n", deviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with creation of the instance of the ImageGrabber class\n", deviceID);
} }
} }
...@@ -1633,8 +1814,7 @@ void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int, ...@@ -1633,8 +1814,7 @@ void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int,
ImageGrabberThread::~ImageGrabberThread(void) ImageGrabberThread::~ImageGrabberThread(void)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
if (igt_Handle) if (igt_Handle)
WaitForSingleObject(igt_Handle, INFINITE); WaitForSingleObject(igt_Handle, INFINITE);
delete igt_pImageGrabber; delete igt_pImageGrabber;
...@@ -1662,30 +1842,29 @@ void ImageGrabberThread::start() ...@@ -1662,30 +1842,29 @@ void ImageGrabberThread::start()
void ImageGrabberThread::run() void ImageGrabberThread::run()
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if(igt_pImageGrabber) if(igt_pImageGrabber)
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID);
HRESULT hr = igt_pImageGrabber->startGrabbing(); HRESULT hr = igt_pImageGrabber->startGrabbing();
if(!SUCCEEDED(hr)) if(!SUCCEEDED(hr))
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID);
} }
} }
else else
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID);
} }
if(!igt_stop) if(!igt_stop)
{ {
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID);
if(igt_func) if(igt_func)
{ {
igt_func(igt_DeviceID, igt_userData); igt_func(igt_DeviceID, igt_userData);
} }
} }
else else
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID); DebugPrintOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID);
} }
ImageGrabber *ImageGrabberThread::getImageGrabber() ImageGrabber *ImageGrabberThread::getImageGrabber()
...@@ -1698,8 +1877,7 @@ Media_Foundation::Media_Foundation(void) ...@@ -1698,8 +1877,7 @@ Media_Foundation::Media_Foundation(void)
HRESULT hr = MFStartup(MF_VERSION); HRESULT hr = MFStartup(MF_VERSION);
if(!SUCCEEDED(hr)) if(!SUCCEEDED(hr))
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
DPO->printOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
} }
} }
...@@ -1708,8 +1886,7 @@ Media_Foundation::~Media_Foundation(void) ...@@ -1708,8 +1886,7 @@ Media_Foundation::~Media_Foundation(void)
HRESULT hr = MFShutdown(); HRESULT hr = MFShutdown();
if(!SUCCEEDED(hr)) if(!SUCCEEDED(hr))
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
DPO->printOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
} }
} }
...@@ -1720,7 +1897,7 @@ bool Media_Foundation::buildListOfDevices() ...@@ -1720,7 +1897,7 @@ bool Media_Foundation::buildListOfDevices()
videoDevices *vDs = &videoDevices::getInstance(); videoDevices *vDs = &videoDevices::getInstance();
hr = vDs->initDevices(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture)); hr = vDs->initDevices(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture));
#else #else
ComPtr<IMFAttributes> pAttributes = NULL; _ComPtr<IMFAttributes> pAttributes = NULL;
CoInitialize(NULL); CoInitialize(NULL);
hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1); hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
...@@ -1738,8 +1915,7 @@ bool Media_Foundation::buildListOfDevices() ...@@ -1738,8 +1915,7 @@ bool Media_Foundation::buildListOfDevices()
#endif #endif
if (FAILED(hr)) if (FAILED(hr))
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
DPO->printOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
} }
return (SUCCEEDED(hr)); return (SUCCEEDED(hr));
...@@ -1803,11 +1979,11 @@ unsigned char * RawImage::getpPixels() ...@@ -1803,11 +1979,11 @@ unsigned char * RawImage::getpPixels()
} }
videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL), videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL),
vd_Width(0), vd_Height(0), vd_pSource(NULL), vd_pImGrTh(NULL), vd_func(NULL), vd_userData(NULL) vd_Width(0), vd_Height(0), vd_FrameRate(0), vd_pSource(NULL), vd_pImGrTh(NULL), vd_func(NULL), vd_userData(NULL)
{ {
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
vd_pMedCap = nullptr; vd_pMedCap = nullptr;
vd_pMedCapFail = NULL; vd_cookie.value = 0;
vd_pImGr = NULL; vd_pImGr = NULL;
vd_pAction = nullptr; vd_pAction = nullptr;
#endif #endif
...@@ -1899,7 +2075,7 @@ long videoDevice::resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice) ...@@ -1899,7 +2075,7 @@ long videoDevice::resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice)
long videoDevice::resetDevice(IMFActivate *pActivate) long videoDevice::resetDevice(IMFActivate *pActivate)
#endif #endif
{ {
HRESULT hr = -1; HRESULT hr = E_FAIL;
vd_CurrentFormats.clear(); vd_CurrentFormats.clear();
if(vd_pFriendlyName) if(vd_pFriendlyName)
CoTaskMemFree(vd_pFriendlyName); CoTaskMemFree(vd_pFriendlyName);
...@@ -1926,25 +2102,28 @@ long videoDevice::resetDevice(IMFActivate *pActivate) ...@@ -1926,25 +2102,28 @@ long videoDevice::resetDevice(IMFActivate *pActivate)
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
MAKE_WRL_REF(_AsyncAction) pAction; MAKE_WRL_REF(_AsyncAction) pAction;
WRL_METHOD(DEREF_WRL_OBJ(pIMedCap), _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet)) WRL_METHOD(DEREF_WRL_OBJ(pIMedCap), _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet))
#ifdef HAVE_CONCURRENCY
DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
MAKE_WRL_AGILE_REF(_MediaCapture) pAgileMedCap; MAKE_WRL_AGILE_REF(_MediaCapture) pAgileMedCap;
pAgileMedCap = PREPARE_TRANSFER_WRL_OBJ(pIMedCap); pAgileMedCap = PREPARE_TRANSFER_WRL_OBJ(pIMedCap);
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock); Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction; MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
SAVE_CURRENT_CONTEXT(context); SAVE_CURRENT_CONTEXT(context);
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, pOldAction, context, &pAgileMedCap, this) vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, pOldAction, context, &pAgileMedCap, this)
HRESULT hr; HRESULT hr = S_OK;
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT); if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context); _task.wait();
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
//all camera capture calls only in original context //all camera capture calls only in original context
BEGIN_CALL_IN_CONTEXT(hr, context, pAgileMedCap, this) BEGIN_CALL_IN_CONTEXT(hr, context, pAgileMedCap, this)
enumerateCaptureFormats(DEREF_AGILE_WRL_OBJ(pAgileMedCap)); enumerateCaptureFormats(DEREF_AGILE_WRL_OBJ(pAgileMedCap));
END_CALL_IN_CONTEXT(S_OK) END_CALL_IN_CONTEXT_BASE
} }
buildLibraryofTypes(); buildLibraryofTypes();
RELEASE_AGILE_WRL(pAgileMedCap) RELEASE_AGILE_WRL(pAgileMedCap)
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#endif
} }
#else #else
if(pActivate) if(pActivate)
...@@ -1965,8 +2144,7 @@ long videoDevice::resetDevice(IMFActivate *pActivate) ...@@ -1965,8 +2144,7 @@ long videoDevice::resetDevice(IMFActivate *pActivate)
if(FAILED(hr)) if(FAILED(hr))
{ {
vd_pFriendlyName = NULL; vd_pFriendlyName = NULL;
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber);
DPO->printOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber);
} }
} }
#endif #endif
...@@ -1984,15 +2162,14 @@ long videoDevice::readInfoOfDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice, un ...@@ -1984,15 +2162,14 @@ long videoDevice::readInfoOfDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice, un
#else #else
long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num) long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num)
{ {
HRESULT hr = -1;
vd_CurrentNumber = Num; vd_CurrentNumber = Num;
hr = resetDevice(pActivate); return resetDevice(pActivate);
return hr;
} }
#endif #endif
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice) #ifdef HAVE_CONCURRENCY
long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<void>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation, MAKE_WRL_OBJ(_DeviceInformationStatics), pDevStat, hr) ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation, MAKE_WRL_OBJ(_DeviceInformationStatics), pDevStat, hr)
...@@ -2000,10 +2177,10 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask ...@@ -2000,10 +2177,10 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask
MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction; MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass) WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
*pTask = CREATE_TASK([pAction, &ppDevice, this]() -> HRESULT { *pTask = CREATE_TASK DEFINE_RET_TYPE(void)([pAction, &ppDevice, this]() -> DEFINE_RET_FORMAL(void) {
HRESULT hr; HRESULT hr = S_OK;
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector; MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector =
DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection); CREATE_TASK DEFINE_RET_TYPE(MAKE_WRL_REF(_VectorView<MAKE_WRL_REF(_DeviceInformation)>))(pAction).get();
UINT32 count = 0; UINT32 count = 0;
if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr) if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
if (SUCCEEDED(hr) && count > 0) { if (SUCCEEDED(hr) && count > 0) {
...@@ -2021,20 +2198,19 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask ...@@ -2021,20 +2198,19 @@ long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask
} }
} }
} }
return hr; RET_VAL_BASE;
}); });
} }
return hr; return hr;
} }
#endif
#else #else
long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice) long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
{ {
HRESULT hr = S_OK;
IMFActivate **ppDevices = NULL; IMFActivate **ppDevices = NULL;
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
UINT32 count; UINT32 count;
wchar_t *newFriendlyName = NULL; wchar_t *newFriendlyName = NULL;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); HRESULT hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if(count > 0) if(count > 0)
...@@ -2050,8 +2226,8 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice) ...@@ -2050,8 +2226,8 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
{ {
if(wcscmp(newFriendlyName, vd_pFriendlyName) != 0) if(wcscmp(newFriendlyName, vd_pFriendlyName) != 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber);
hr = -1; hr = E_INVALIDARG;
pDevice = NULL; pDevice = NULL;
} }
else else
...@@ -2062,13 +2238,13 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice) ...@@ -2062,13 +2238,13 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber);
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber);
hr = -1; hr = E_INVALIDARG;
} }
for(UINT32 i = 0; i < count; i++) for(UINT32 i = 0; i < count; i++)
{ {
...@@ -2077,11 +2253,11 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice) ...@@ -2077,11 +2253,11 @@ long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
SafeRelease(ppDevices); SafeRelease(ppDevices);
} }
else else
hr = -1; hr = E_FAIL;
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber);
} }
return hr; return hr;
} }
...@@ -2092,19 +2268,20 @@ long videoDevice::initDevice() ...@@ -2092,19 +2268,20 @@ long videoDevice::initDevice()
HRESULT hr = S_OK; HRESULT hr = S_OK;
CoInitialize(NULL); CoInitialize(NULL);
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock); Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction; MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
SAVE_CURRENT_CONTEXT(context); SAVE_CURRENT_CONTEXT(context);
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, this) vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pOldAction, context, this)
HRESULT hr; HRESULT hr;
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT); if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
DEFINE_TASK<HRESULT> pTask; DEFINE_TASK<void> pTask;
MAKE_WRL_OBJ(_IDeviceInformation) pDevInfo; MAKE_WRL_OBJ(_IDeviceInformation) pDevInfo;
hr = checkDevice(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture), &pTask, REF_WRL_OBJ(pDevInfo)); hr = checkDevice(WRL_ENUM_GET(_DeviceClass, DeviceClass, VideoCapture), &pTask, REF_WRL_OBJ(pDevInfo));
if (SUCCEEDED(hr)) hr = pTask.get(); if (SUCCEEDED(hr)) pTask.wait();
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
MAKE_WRL_REF(_AsyncAction) pAction; DEFINE_TASK<void> _task;
BEGIN_CALL_IN_CONTEXT(hr, context, pDevInfo, &pAction, context, this) BEGIN_CALL_IN_CONTEXT(hr, context, pDevInfo, &_task, context, this)
HRESULT hr; HRESULT hr;
ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCapture, _MediaCapture, pIMedCap, hr) ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCapture, _MediaCapture, pIMedCap, hr)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
...@@ -2120,24 +2297,24 @@ long videoDevice::initDevice() ...@@ -2120,24 +2297,24 @@ long videoDevice::initDevice()
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
WRL_PROP_PUT(pCapInitSet, StreamingCaptureMode, WRL_ENUM_GET(_StreamingCaptureMode, StreamingCaptureMode, Video), hr) WRL_PROP_PUT(pCapInitSet, StreamingCaptureMode, WRL_ENUM_GET(_StreamingCaptureMode, StreamingCaptureMode, Video), hr)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))->add_Failed(Microsoft::WRL::Callback<ABI::Windows::Media::Capture::IMediaCaptureFailedEventHandler>([this, context](ABI::Windows::Media::Capture::IMediaCapture*, ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs*) -> HRESULT {
vd_pMedCapFail = create_medcapfailedhandler([this, context](){
HRESULT hr; HRESULT hr;
BEGIN_CALL_IN_CONTEXT(hr, context, this) BEGIN_CALL_IN_CONTEXT(hr, context, this)
closeDevice(); closeDevice();
END_CALL_IN_CONTEXT(S_OK) END_CALL_IN_CONTEXT_BASE
}); return hr;
} }).Get(), &vd_cookie);
if (SUCCEEDED(hr)) hr = vd_pMedCapFail->AddHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))); MAKE_WRL_OBJ(_AsyncAction) pAction;
if (SUCCEEDED(hr)) WRL_METHOD(vd_pMedCap, _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet)) if (SUCCEEDED(hr)) WRL_METHOD(vd_pMedCap, _InitializeWithSettingsAsync, *REF_WRL_OBJ(pAction), hr, DEREF_WRL_OBJ(pCapInitSet))
if (SUCCEEDED(hr)) _task = CREATE_TASK DEFINE_RET_TYPE(void)(DEREF_WRL_OBJ(pAction));
} }
END_CALL_IN_CONTEXT(hr) END_CALL_IN_CONTEXT(hr)
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context); _task.wait();
} }
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#endif
#else #else
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); _ComPtr<IMFAttributes> pAttributes = NULL;
ComPtr<IMFAttributes> pAttributes = NULL;
IMFActivate *vd_pActivate = NULL; IMFActivate *vd_pActivate = NULL;
hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1); hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
...@@ -2164,12 +2341,12 @@ long videoDevice::initDevice() ...@@ -2164,12 +2341,12 @@ long videoDevice::initDevice()
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber);
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber);
} }
#endif #endif
return hr; return hr;
...@@ -2199,17 +2376,18 @@ void videoDevice::closeDevice() ...@@ -2199,17 +2376,18 @@ void videoDevice::closeDevice()
vd_IsSetuped = false; vd_IsSetuped = false;
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) { if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
MAKE_WRL_REF(_AsyncAction) action; MAKE_WRL_REF(_AsyncAction) action;
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock); Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction; MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
vd_pImGr->stopGrabbing(&action); vd_pImGr->stopGrabbing(&action);
vd_pMedCapFail->RemoveHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))); reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap))->remove_Failed(vd_cookie);
SafeRelease(&vd_pMedCapFail); vd_cookie.value = 0;
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, this) vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, action, pOldAction, this)
HRESULT hr; HRESULT hr = S_OK;
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT); if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
DO_ACTION_SYNCHRONOUSLY(hr, action, GET_CURRENT_CONTEXT); CREATE_TASK DEFINE_RET_TYPE(void)(action).wait();
RELEASE_WRL(vd_pMedCap) RELEASE_WRL(vd_pMedCap)
if(vd_LockOut == RawDataLock) { if(vd_LockOut == RawDataLock) {
delete vd_pImGr; delete vd_pImGr;
...@@ -2219,9 +2397,10 @@ void videoDevice::closeDevice() ...@@ -2219,9 +2397,10 @@ void videoDevice::closeDevice()
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
return; return;
} }
#endif
#endif #endif
vd_pSource->Stop(); vd_pSource->Shutdown();
SafeRelease(&vd_pSource); SafeRelease(&vd_pSource);
if(vd_LockOut == RawDataLock) if(vd_LockOut == RawDataLock)
{ {
...@@ -2231,8 +2410,7 @@ void videoDevice::closeDevice() ...@@ -2231,8 +2410,7 @@ void videoDevice::closeDevice()
} }
vd_pImGrTh = NULL; vd_pImGrTh = NULL;
vd_LockOut = OpenLock; vd_LockOut = OpenLock;
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber);
DPO->printOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber);
} }
} }
unsigned int videoDevice::getWidth() unsigned int videoDevice::getWidth()
...@@ -2249,6 +2427,15 @@ unsigned int videoDevice::getHeight() ...@@ -2249,6 +2427,15 @@ unsigned int videoDevice::getHeight()
else else
return 0; return 0;
} }
unsigned int videoDevice::getFrameRate() const
{
if(vd_IsSetuped)
return vd_FrameRate;
else
return 0;
}
IMFMediaSource *videoDevice::getMediaSource() IMFMediaSource *videoDevice::getMediaSource()
{ {
IMFMediaSource *out = NULL; IMFMediaSource *out = NULL;
...@@ -2261,17 +2448,26 @@ IMFMediaSource *videoDevice::getMediaSource() ...@@ -2261,17 +2448,26 @@ IMFMediaSource *videoDevice::getMediaSource()
} }
int videoDevice::findType(unsigned int size, unsigned int frameRate) int videoDevice::findType(unsigned int size, unsigned int frameRate)
{ {
if(vd_CaptureFormats.size() == 0) // For required frame size look for the suitable video format.
return 0; // If not found, get the format for the largest available frame size.
FrameRateMap FRM = vd_CaptureFormats[size]; FrameRateMap FRM;
if(FRM.size() == 0) std::map<UINT64, FrameRateMap>::const_iterator fmt;
return 0; fmt = vd_CaptureFormats.find(size);
if( fmt != vd_CaptureFormats.end() )
FRM = fmt->second;
else
FRM = vd_CaptureFormats.rbegin()->second;
if( FRM.empty() )
return -1;
UINT64 frameRateMax = 0; SUBTYPEMap STMMax; UINT64 frameRateMax = 0; SUBTYPEMap STMMax;
if(frameRate == 0) if(frameRate == 0)
{ {
std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin(); std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
for(; f != FRM.end(); f++) for(; f != FRM.end(); f++)
{ {
// Looking for highest possible frame rate.
if((*f).first >= frameRateMax) if((*f).first >= frameRateMax)
{ {
frameRateMax = (*f).first; frameRateMax = (*f).first;
...@@ -2284,22 +2480,26 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate) ...@@ -2284,22 +2480,26 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate)
std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin(); std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
for(; f != FRM.end(); f++) for(; f != FRM.end(); f++)
{ {
if((*f).first >= frameRateMax) // Looking for frame rate higher that recently found but not higher then demanded.
{ if( (*f).first >= frameRateMax && (*f).first <= frameRate )
if(frameRate > (*f).first)
{ {
frameRateMax = (*f).first; frameRateMax = (*f).first;
STMMax = (*f).second; STMMax = (*f).second;
} }
} }
} }
} // Get first (default) item from the list if no suitable frame rate found.
if(STMMax.size() == 0) if( STMMax.empty() )
return 0; STMMax = FRM.begin()->second;
std::map<String, vectorNum>::iterator S = STMMax.begin();
vectorNum VN = (*S).second; // Check if there are any format types on the list.
if(VN.size() == 0) if( STMMax.empty() )
return 0; return -1;
vectorNum VN = STMMax.begin()->second;
if( VN.empty() )
return -1;
return VN[0]; return VN[0];
} }
...@@ -2310,9 +2510,12 @@ void videoDevice::buildLibraryofTypes() ...@@ -2310,9 +2510,12 @@ void videoDevice::buildLibraryofTypes()
std::vector<MediaType>::iterator i = vd_CurrentFormats.begin(); std::vector<MediaType>::iterator i = vd_CurrentFormats.begin();
int count = 0; int count = 0;
for(; i != vd_CurrentFormats.end(); i++) for(; i != vd_CurrentFormats.end(); i++)
{
// Count only supported video formats.
if( (*i).MF_MT_SUBTYPE == MFVideoFormat_RGB24 )
{ {
size = (*i).MF_MT_FRAME_SIZE; size = (*i).MF_MT_FRAME_SIZE;
framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR; framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR / (*i).MF_MT_FRAME_RATE_DENOMINATOR;
FrameRateMap FRM = vd_CaptureFormats[size]; FrameRateMap FRM = vd_CaptureFormats[size];
SUBTYPEMap STM = FRM[framerate]; SUBTYPEMap STM = FRM[framerate];
String subType((*i).pMF_MT_SUBTYPEName); String subType((*i).pMF_MT_SUBTYPEName);
...@@ -2321,6 +2524,7 @@ void videoDevice::buildLibraryofTypes() ...@@ -2321,6 +2524,7 @@ void videoDevice::buildLibraryofTypes()
STM[subType] = VN; STM[subType] = VN;
FRM[framerate] = STM; FRM[framerate] = STM;
vd_CaptureFormats[size] = FRM; vd_CaptureFormats[size] = FRM;
}
count++; count++;
} }
} }
...@@ -2347,10 +2551,10 @@ long videoDevice::setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned ...@@ -2347,10 +2551,10 @@ long videoDevice::setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned
long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex) long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex)
{ {
ComPtr<IMFPresentationDescriptor> pPD = NULL; _ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL; _ComPtr<IMFStreamDescriptor> pSD = NULL;
ComPtr<IMFMediaTypeHandler> pHandler = NULL; _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf()); HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -2393,8 +2597,7 @@ RawImage * videoDevice::getRawImageOut() ...@@ -2393,8 +2597,7 @@ RawImage * videoDevice::getRawImageOut()
return vd_pImGrTh->getImageGrabber()->getRawImage(); return vd_pImGrTh->getImageGrabber()->getRawImage();
else else
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist \n", vd_CurrentNumber);
DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist \n", vd_CurrentNumber);
} }
return NULL; return NULL;
} }
...@@ -2417,22 +2620,23 @@ bool videoDevice::isFrameNew() ...@@ -2417,22 +2620,23 @@ bool videoDevice::isFrameNew()
delete vd_pImGr; delete vd_pImGr;
return false; return false;
} }
#ifdef HAVE_CONCURRENCY
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock); Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction; MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
SAVE_CURRENT_CONTEXT(context); DEFINE_TASK<void> _task = CREATE_TASK DEFINE_RET_TYPE(void)(action);
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, context, this) vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, _task, pOldAction, this)
HRESULT hr; HRESULT hr = S_OK;
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT); if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
DO_ACTION_SYNCHRONOUSLY(hr, action, context); _task.wait();
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#endif
return true; return true;
} }
#endif #endif
HRESULT hr = ImageGrabberThread::CreateInstance(&vd_pImGrTh, vd_pSource, vd_CurrentNumber); HRESULT hr = ImageGrabberThread::CreateInstance(&vd_pImGrTh, vd_pSource, vd_CurrentNumber);
if(FAILED(hr)) if(FAILED(hr))
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber);
DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber);
return false; return false;
} }
vd_pImGrTh->setEmergencyStopEvent(vd_userData, vd_func); vd_pImGrTh->setEmergencyStopEvent(vd_userData, vd_func);
...@@ -2463,38 +2667,47 @@ bool videoDevice::isDeviceRawDataSource() ...@@ -2463,38 +2667,47 @@ bool videoDevice::isDeviceRawDataSource()
bool videoDevice::setupDevice(unsigned int id) bool videoDevice::setupDevice(unsigned int id)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if(!vd_IsSetuped) if(!vd_IsSetuped)
{ {
HRESULT hr = -1; HRESULT hr = initDevice();
hr = initDevice();
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock); Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction; MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
SAVE_CURRENT_CONTEXT(context); SAVE_CURRENT_CONTEXT(context);
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, id, DPO, this) vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pOldAction, context, id, this)
HRESULT hr; HRESULT hr;
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT); if (pOldAction) CREATE_TASK DEFINE_RET_TYPE(void)(pOldAction).wait();
#endif
#endif #endif
vd_Width = vd_CurrentFormats[id].width; vd_Width = vd_CurrentFormats[id].width;
vd_Height = vd_CurrentFormats[id].height; vd_Height = vd_CurrentFormats[id].height;
vd_FrameRate = vd_CurrentFormats[id].MF_MT_FRAME_RATE_NUMERATOR /
vd_CurrentFormats[id].MF_MT_FRAME_RATE_DENOMINATOR;
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) { if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
DEFINE_TASK<void> _task;
BEGIN_CALL_IN_CONTEXT(hr, context, id, &_task, this)
MAKE_WRL_REF(_AsyncAction) pAction; MAKE_WRL_REF(_AsyncAction) pAction;
BEGIN_CALL_IN_CONTEXT(hr, context, id, &pAction, this) HRESULT hr = setDeviceFormat(DEREF_AGILE_WRL_OBJ(vd_pMedCap), (DWORD) id, &pAction);
END_CALL_IN_CONTEXT(setDeviceFormat(DEREF_AGILE_WRL_OBJ(vd_pMedCap), (DWORD) id, &pAction)) if (SUCCEEDED(hr)) _task = CREATE_TASK DEFINE_RET_TYPE(void)(pAction);
if (SUCCEEDED(hr)) DO_ACTION_SYNCHRONOUSLY(hr, pAction, context); END_CALL_IN_CONTEXT(hr)
if (SUCCEEDED(hr)) _task.wait();
} else } else
#endif
#endif #endif
hr = setDeviceFormat(vd_pSource, (DWORD) id); hr = setDeviceFormat(vd_pSource, (DWORD) id);
vd_IsSetuped = (SUCCEEDED(hr)); vd_IsSetuped = (SUCCEEDED(hr));
if(vd_IsSetuped) if(vd_IsSetuped)
DPO->printOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber); DebugPrintOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber);
vd_PrevParametrs = getParametrs(); vd_PrevParametrs = getParametrs();
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#endif
return true; return true;
#else #else
return vd_IsSetuped; return vd_IsSetuped;
...@@ -2502,13 +2715,13 @@ bool videoDevice::setupDevice(unsigned int id) ...@@ -2502,13 +2715,13 @@ bool videoDevice::setupDevice(unsigned int id)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber);
return false; return false;
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber); DebugPrintOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber);
return false; return false;
} }
} }
...@@ -2516,6 +2729,9 @@ bool videoDevice::setupDevice(unsigned int id) ...@@ -2516,6 +2729,9 @@ bool videoDevice::setupDevice(unsigned int id)
bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate) bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate)
{ {
unsigned int id = findType(w * h, idealFramerate); unsigned int id = findType(w * h, idealFramerate);
if( id < 0 )
return false;
return setupDevice(id); return setupDevice(id);
} }
...@@ -2554,7 +2770,7 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource ...@@ -2554,7 +2770,7 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource
MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps; MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
WRL_METHOD(pVector, GetAt, pMedEncProps, hr, i) WRL_METHOD(pVector, GetAt, pMedEncProps, hr, i)
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType); hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
MediaType MT = FormatReader::Read(pType.Get()); MediaType MT = FormatReader::Read(pType.Get());
...@@ -2566,10 +2782,10 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource ...@@ -2566,10 +2782,10 @@ HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource
HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource) HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
{ {
ComPtr<IMFPresentationDescriptor> pPD = NULL; _ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL; _ComPtr<IMFStreamDescriptor> pSD = NULL;
ComPtr<IMFMediaTypeHandler> pHandler = NULL; _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf()); HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -2649,11 +2865,12 @@ long videoDevices::initDevices(_DeviceClass devClass) ...@@ -2649,11 +2865,12 @@ long videoDevices::initDevices(_DeviceClass devClass)
MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction; MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass) WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
#ifdef HAVE_CONCURRENCY
SAVE_CURRENT_CONTEXT(context); SAVE_CURRENT_CONTEXT(context);
vds_enumTask = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this) vds_enumTask = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(void, pAction, context, this)
HRESULT hr; HRESULT hr = S_OK;
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector; MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector =
DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection); CREATE_TASK DEFINE_RET_TYPE(MAKE_WRL_REF(_VectorView<MAKE_WRL_REF(_DeviceInformation)>))(pAction).get();
if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr) if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
if (SUCCEEDED(hr) && count > 0) { if (SUCCEEDED(hr) && count > 0) {
for (UINT32 i = 0; i < count; i++) { for (UINT32 i = 0; i < count; i++) {
...@@ -2663,22 +2880,22 @@ long videoDevices::initDevices(_DeviceClass devClass) ...@@ -2663,22 +2880,22 @@ long videoDevices::initDevices(_DeviceClass devClass)
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
BEGIN_CALL_IN_CONTEXT(hr, context, vd, pDevice, i) BEGIN_CALL_IN_CONTEXT(hr, context, vd, pDevice, i)
vd->readInfoOfDevice(DEREF_WRL_OBJ(pDevice), i); vd->readInfoOfDevice(DEREF_WRL_OBJ(pDevice), i);
END_CALL_IN_CONTEXT(S_OK) END_CALL_IN_CONTEXT_BASE
vds_Devices.push_back(vd); vds_Devices.push_back(vd);
} }
} }
} }
END_CREATE_ASYNC(hr)); END_CREATE_ASYNC(hr));
#endif
} }
return hr; return hr;
} }
#else #else
long videoDevices::initDevices(IMFAttributes *pAttributes) long videoDevices::initDevices(IMFAttributes *pAttributes)
{ {
HRESULT hr = S_OK;
clearDevices(); clearDevices();
IMFActivate **ppDevices = NULL; IMFActivate **ppDevices = NULL;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); HRESULT hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if(count > 0) if(count > 0)
...@@ -2693,12 +2910,11 @@ long videoDevices::initDevices(IMFAttributes *pAttributes) ...@@ -2693,12 +2910,11 @@ long videoDevices::initDevices(IMFAttributes *pAttributes)
SafeRelease(ppDevices); SafeRelease(ppDevices);
} }
else else
hr = -1; hr = E_INVALIDARG;
} }
else else
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n");
DPO->printOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n");
} }
return hr; return hr;
} }
...@@ -2768,56 +2984,50 @@ void MediaType::Clear() ...@@ -2768,56 +2984,50 @@ void MediaType::Clear()
videoInput::videoInput(void): accessToDevices(false) videoInput::videoInput(void): accessToDevices(false)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n");
DPO->printOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n");
updateListOfDevices(); updateListOfDevices();
if(!accessToDevices) if(!accessToDevices)
DPO->printOut(L"INITIALIZATION: There is not any suitable video device\n"); DebugPrintOut(L"INITIALIZATION: There is not any suitable video device\n");
} }
void videoInput::updateListOfDevices() void videoInput::updateListOfDevices()
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
Media_Foundation *MF = &Media_Foundation::getInstance(); Media_Foundation *MF = &Media_Foundation::getInstance();
accessToDevices = MF->buildListOfDevices(); accessToDevices = MF->buildListOfDevices();
if(!accessToDevices) if(!accessToDevices)
DPO->printOut(L"UPDATING: There is not any suitable video device\n"); DebugPrintOut(L"UPDATING: There is not any suitable video device\n");
} }
videoInput::~videoInput(void) videoInput::~videoInput(void)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
DPO->printOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
} }
IMFMediaSource *videoInput::getMediaSource(int deviceID) IMFMediaSource *videoInput::getMediaSource(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if(accessToDevices) if(accessToDevices)
{ {
videoDevices *VDS = &videoDevices::getInstance(); videoDevice * VD = videoDevices::getInstance().getDevice(deviceID);
videoDevice * VD = VDS->getDevice(deviceID);
if(VD) if(VD)
{ {
IMFMediaSource *out = VD->getMediaSource(); IMFMediaSource *out = VD->getMediaSource();
if(!out) if(!out)
DPO->printOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID); DebugPrintOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID);
return out; return out;
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return NULL; return NULL;
} }
bool videoInput::setupDevice(int deviceID, unsigned int id) bool videoInput::setupDevice(int deviceID, unsigned int id)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0 ) if (deviceID < 0 )
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2828,23 +3038,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int id) ...@@ -2828,23 +3038,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int id)
{ {
bool out = VD->setupDevice(id); bool out = VD->setupDevice(id);
if(!out) if(!out)
DPO->printOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID);
return out; return out;
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return false; return false;
} }
bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate) bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0 ) if (deviceID < 0 )
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2855,23 +3064,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsig ...@@ -2855,23 +3064,22 @@ bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsig
{ {
bool out = VD->setupDevice(w, h, idealFramerate); bool out = VD->setupDevice(w, h, idealFramerate);
if(!out) if(!out)
DPO->printOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID);
return out; return out;
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID);
} }
return false; return false;
} }
MediaType videoInput::getFormat(int deviceID, unsigned int id) MediaType videoInput::getFormat(int deviceID, unsigned int id)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return MediaType(); return MediaType();
} }
if(accessToDevices) if(accessToDevices)
...@@ -2883,17 +3091,16 @@ MediaType videoInput::getFormat(int deviceID, unsigned int id) ...@@ -2883,17 +3091,16 @@ MediaType videoInput::getFormat(int deviceID, unsigned int id)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return MediaType(); return MediaType();
} }
bool videoInput::isDeviceSetup(int deviceID) bool videoInput::isDeviceSetup(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2905,17 +3112,16 @@ bool videoInput::isDeviceSetup(int deviceID) ...@@ -2905,17 +3112,16 @@ bool videoInput::isDeviceSetup(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return false; return false;
} }
bool videoInput::isDeviceMediaSource(int deviceID) bool videoInput::isDeviceMediaSource(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2927,17 +3133,16 @@ bool videoInput::isDeviceMediaSource(int deviceID) ...@@ -2927,17 +3133,16 @@ bool videoInput::isDeviceMediaSource(int deviceID)
} }
else else
{ {
DPO->printOut(L"Device(s): There is not any suitable video device\n"); DebugPrintOut(L"Device(s): There is not any suitable video device\n");
} }
return false; return false;
} }
bool videoInput::isDeviceRawDataSource(int deviceID) bool videoInput::isDeviceRawDataSource(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2952,17 +3157,16 @@ bool videoInput::isDeviceRawDataSource(int deviceID) ...@@ -2952,17 +3157,16 @@ bool videoInput::isDeviceRawDataSource(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return false; return false;
} }
bool videoInput::isFrameNew(int deviceID) bool videoInput::isFrameNew(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return false; return false;
} }
if(accessToDevices) if(accessToDevices)
...@@ -2981,7 +3185,7 @@ bool videoInput::isFrameNew(int deviceID) ...@@ -2981,7 +3185,7 @@ bool videoInput::isFrameNew(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return false; return false;
} }
...@@ -2989,10 +3193,9 @@ bool videoInput::isFrameNew(int deviceID) ...@@ -2989,10 +3193,9 @@ bool videoInput::isFrameNew(int deviceID)
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
void videoInput::waitForDevice(int deviceID) void videoInput::waitForDevice(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return; return;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3011,7 +3214,7 @@ void videoInput::waitForDevice(int deviceID) ...@@ -3011,7 +3214,7 @@ void videoInput::waitForDevice(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return; return;
} }
...@@ -3019,10 +3222,9 @@ void videoInput::waitForDevice(int deviceID) ...@@ -3019,10 +3222,9 @@ void videoInput::waitForDevice(int deviceID)
unsigned int videoInput::getCountFormats(int deviceID) unsigned int videoInput::getCountFormats(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return 0; return 0;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3034,7 +3236,7 @@ unsigned int videoInput::getCountFormats(int deviceID) ...@@ -3034,7 +3236,7 @@ unsigned int videoInput::getCountFormats(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return 0; return 0;
} }
...@@ -3048,10 +3250,9 @@ void videoInput::closeAllDevices() ...@@ -3048,10 +3250,9 @@ void videoInput::closeAllDevices()
void videoInput::setParametrs(int deviceID, CamParametrs parametrs) void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return; return;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3063,17 +3264,16 @@ void videoInput::setParametrs(int deviceID, CamParametrs parametrs) ...@@ -3063,17 +3264,16 @@ void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
} }
CamParametrs videoInput::getParametrs(int deviceID) CamParametrs videoInput::getParametrs(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
CamParametrs out; CamParametrs out;
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return out; return out;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3085,17 +3285,16 @@ CamParametrs videoInput::getParametrs(int deviceID) ...@@ -3085,17 +3285,16 @@ CamParametrs videoInput::getParametrs(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return out; return out;
} }
void videoInput::closeDevice(int deviceID) void videoInput::closeDevice(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return; return;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3107,16 +3306,15 @@ void videoInput::closeDevice(int deviceID) ...@@ -3107,16 +3306,15 @@ void videoInput::closeDevice(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
} }
unsigned int videoInput::getWidth(int deviceID) unsigned int videoInput::getWidth(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return 0; return 0;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3128,17 +3326,16 @@ unsigned int videoInput::getWidth(int deviceID) ...@@ -3128,17 +3326,16 @@ unsigned int videoInput::getWidth(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return 0; return 0;
} }
unsigned int videoInput::getHeight(int deviceID) unsigned int videoInput::getHeight(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return 0; return 0;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3150,17 +3347,36 @@ unsigned int videoInput::getHeight(int deviceID) ...@@ -3150,17 +3347,36 @@ unsigned int videoInput::getHeight(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
}
return 0;
}
unsigned int videoInput::getFrameRate(int deviceID) const
{
if (deviceID < 0)
{
DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return 0;
}
if(accessToDevices)
{
videoDevice * VD = videoDevices::getInstance().getDevice(deviceID);
if(VD)
return VD->getFrameRate();
}
else
{
DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return 0; return 0;
} }
wchar_t *videoInput::getNameVideoDevice(int deviceID) wchar_t *videoInput::getNameVideoDevice(int deviceID)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return NULL; return NULL;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3172,14 +3388,13 @@ wchar_t *videoInput::getNameVideoDevice(int deviceID) ...@@ -3172,14 +3388,13 @@ wchar_t *videoInput::getNameVideoDevice(int deviceID)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return L"Empty"; return L"Empty";
} }
unsigned int videoInput::listDevices(bool silent) unsigned int videoInput::listDevices(bool silent)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
int out = 0; int out = 0;
if(accessToDevices) if(accessToDevices)
{ {
...@@ -3188,18 +3403,17 @@ unsigned int videoInput::listDevices(bool silent) ...@@ -3188,18 +3403,17 @@ unsigned int videoInput::listDevices(bool silent)
VDS->waitInit(); VDS->waitInit();
#endif #endif
out = VDS->getCount(); out = VDS->getCount();
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); if(!silent) DebugPrintOut(L"\nVIDEOINPUT SPY MODE!\n\n");
if(!silent)DPO->printOut(L"\nVIDEOINPUT SPY MODE!\n\n"); if(!silent) DebugPrintOut(L"SETUP: Looking For Capture Devices\n");
if(!silent)DPO->printOut(L"SETUP: Looking For Capture Devices\n");
for(int i = 0; i < out; i++) for(int i = 0; i < out; i++)
{ {
if(!silent)DPO->printOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i)); if(!silent) DebugPrintOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i));
} }
if(!silent)DPO->printOut(L"SETUP: %i Device(s) found\n\n", out); if(!silent) DebugPrintOut(L"SETUP: %i Device(s) found\n\n", out);
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return out; return out;
} }
...@@ -3215,18 +3429,19 @@ bool videoInput::isDevicesAcceable() ...@@ -3215,18 +3429,19 @@ bool videoInput::isDevicesAcceable()
return accessToDevices; return accessToDevices;
} }
#ifdef _DEBUG
void videoInput::setVerbose(bool state) void videoInput::setVerbose(bool state)
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DPO *dpo = &DPO::getInstance();
DPO->setVerbose(state); dpo->setVerbose(state);
} }
#endif
void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *)) void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *))
{ {
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return; return;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3241,18 +3456,16 @@ void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func) ...@@ -3241,18 +3456,16 @@ void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
} }
bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage) bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage)
{ {
bool success = false; bool success = false;
unsigned int bytes = 3;
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (deviceID < 0) if (deviceID < 0)
{ {
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID); DebugPrintOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
return success; return success;
} }
if(accessToDevices) if(accessToDevices)
...@@ -3260,14 +3473,14 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed ...@@ -3260,14 +3473,14 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed
bool isRaw = isDeviceRawDataSource(deviceID); bool isRaw = isDeviceRawDataSource(deviceID);
if(isRaw) if(isRaw)
{ {
videoDevices *VDS = &videoDevices::getInstance(); videoDevice *VD = videoDevices::getInstance().getDevice(deviceID);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); RawImage *RIOut = VD->getRawImageOut();
RawImage *RIOut = VDS->getDevice(deviceID)->getRawImageOut();
if(RIOut) if(RIOut)
{ {
unsigned int height = VDS->getDevice(deviceID)->getHeight(); const unsigned int bytes = 3;
unsigned int width = VDS->getDevice(deviceID)->getWidth(); const unsigned int height = VD->getHeight();
unsigned int size = bytes * width * height; const unsigned int width = VD->getWidth();
const unsigned int size = bytes * width * height;
if(size == RIOut->getSize()) if(size == RIOut->getSize())
{ {
processPixels(RIOut->getpPixels(), dstBuffer, width, height, bytes, flipRedAndBlue, flipImage); processPixels(RIOut->getpPixels(), dstBuffer, width, height, bytes, flipRedAndBlue, flipImage);
...@@ -3275,22 +3488,22 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed ...@@ -3275,22 +3488,22 @@ bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRed
} }
else else
{ {
DPO->printOut(L"ERROR: GetPixels() - bufferSizes do not match!\n"); DebugPrintOut(L"ERROR: GetPixels() - bufferSizes do not match!\n");
} }
} }
else else
{ {
DPO->printOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID); DebugPrintOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID);
} }
} }
else else
{ {
DPO->printOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID); DebugPrintOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID);
} }
} }
else else
{ {
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n"); DebugPrintOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
} }
return success; return success;
} }
...@@ -3377,17 +3590,21 @@ protected: ...@@ -3377,17 +3590,21 @@ protected:
IplImage* frame; IplImage* frame;
videoInput VI; videoInput VI;
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
DEFINE_TASK<bool> openTask; DEFINE_TASK<bool> openTask;
Concurrency::critical_section lock; Concurrency::critical_section lock;
#endif #endif
#endif
}; };
#ifdef _DEBUG
struct SuppressVideoInputMessages struct SuppressVideoInputMessages
{ {
SuppressVideoInputMessages() { videoInput::setVerbose(true); } SuppressVideoInputMessages() { videoInput::setVerbose(true); }
}; };
static SuppressVideoInputMessages do_it; static SuppressVideoInputMessages do_it;
#endif
CvCaptureCAM_MSMF::CvCaptureCAM_MSMF(): CvCaptureCAM_MSMF::CvCaptureCAM_MSMF():
index(-1), index(-1),
...@@ -3421,8 +3638,10 @@ void CvCaptureCAM_MSMF::close() ...@@ -3421,8 +3638,10 @@ void CvCaptureCAM_MSMF::close()
bool CvCaptureCAM_MSMF::open( int _index ) bool CvCaptureCAM_MSMF::open( int _index )
{ {
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef HAVE_CONCURRENCY
SAVE_CURRENT_CONTEXT(context); SAVE_CURRENT_CONTEXT(context);
auto func = [_index, context, this]() -> bool { auto func = [_index, context, this](DEFINE_RET_VAL(bool)) -> DEFINE_RET_FORMAL(bool) {
#endif
#endif #endif
int try_index = _index; int try_index = _index;
int devices = 0; int devices = 0;
...@@ -3433,14 +3652,18 @@ bool CvCaptureCAM_MSMF::open( int _index ) ...@@ -3433,14 +3652,18 @@ bool CvCaptureCAM_MSMF::open( int _index )
try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index); try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index);
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
HRESULT hr; HRESULT hr;
#ifdef HAVE_CONCURRENCY
BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index) BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
#endif #endif
VI.setupDevice(try_index); #endif
VI.setupDevice(try_index, 0, 0, 0); // With maximum frame size.
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
END_CALL_IN_CONTEXT(S_OK) #ifdef HAVE_CONCURRENCY
END_CALL_IN_CONTEXT_BASE
VI.waitForDevice(try_index); VI.waitForDevice(try_index);
BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index) BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
HRESULT hr = S_OK; HRESULT hr = S_OK;
#endif
#endif #endif
if( !VI.isFrameNew(try_index) ) if( !VI.isFrameNew(try_index) )
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
...@@ -3450,11 +3673,13 @@ bool CvCaptureCAM_MSMF::open( int _index ) ...@@ -3450,11 +3673,13 @@ bool CvCaptureCAM_MSMF::open( int _index )
#endif #endif
index = try_index; index = try_index;
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
END_CALL_IN_CONTEXT(hr); #ifdef HAVE_CONCURRENCY
return true; END_CALL_IN_CONTEXT_BASE
RET_VAL(true)
}; };
Concurrency::critical_section::scoped_lock _LockHolder(lock); Concurrency::critical_section::scoped_lock _LockHolder(lock);
CREATE_OR_CONTINUE_TASK(openTask, bool, func) CREATE_OR_CONTINUE_TASK(openTask, bool, func)
#endif
#endif #endif
return true; return true;
} }
...@@ -3468,11 +3693,12 @@ bool CvCaptureCAM_MSMF::grabFrame() ...@@ -3468,11 +3693,12 @@ bool CvCaptureCAM_MSMF::grabFrame()
IplImage* CvCaptureCAM_MSMF::retrieveFrame(int) IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
{ {
if( !frame || (int)VI.getWidth(index) != frame->width || (int)VI.getHeight(index) != frame->height ) const int w = (int)VI.getWidth(index);
const int h = (int)VI.getHeight(index);
if( !frame || w != frame->width || h != frame->height )
{ {
if (frame) if (frame)
cvReleaseImage( &frame ); cvReleaseImage( &frame );
unsigned int w = VI.getWidth(index), h = VI.getHeight(index);
frame = cvCreateImage( cvSize(w,h), 8, 3 ); frame = cvCreateImage( cvSize(w,h), 8, 3 );
} }
VI.getPixels( index, (uchar*)frame->imageData, false, true ); VI.getPixels( index, (uchar*)frame->imageData, false, true );
...@@ -3488,33 +3714,47 @@ double CvCaptureCAM_MSMF::getProperty( int property_id ) ...@@ -3488,33 +3714,47 @@ double CvCaptureCAM_MSMF::getProperty( int property_id )
return VI.getWidth(index); return VI.getWidth(index);
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
return VI.getHeight(index); return VI.getHeight(index);
case CV_CAP_PROP_FPS:
return VI.getFrameRate(index);
default:
break;
} }
return -1; return 0;
} }
bool CvCaptureCAM_MSMF::setProperty( int property_id, double value ) bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
{ {
// image capture properties // image capture properties
unsigned int fps = 0;
bool handled = false; bool handled = false;
switch( property_id ) switch( property_id )
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
width = cvRound(value); width = cvRound(value);
fps = VI.getFrameRate(index);
handled = true; handled = true;
break; break;
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
height = cvRound(value); height = cvRound(value);
fps = VI.getFrameRate(index);
handled = true; handled = true;
break; break;
case CV_CAP_PROP_FPS:
width = (int)VI.getHeight(index);
height = (int)VI.getWidth(index);
fps = cvRound(value);
break;
} }
if ( handled ) { if ( handled ) {
if( width > 0 && height > 0 ) if( width > 0 && height > 0 )
{ {
if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) && VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) ) if( (width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) || fps != VI.getFrameRate(index))
&& VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) )
{ {
VI.closeDevice(index); VI.closeDevice(index);
VI.setupDevice(index, width, height); VI.setupDevice(index, width, height, fps);
} }
width = height = -1;
return VI.isDeviceSetup(index); return VI.isDeviceSetup(index);
} }
return true; return true;
...@@ -3573,14 +3813,12 @@ bool CvCaptureFile_MSMF::open(const char* filename) ...@@ -3573,14 +3813,12 @@ bool CvCaptureFile_MSMF::open(const char* filename)
wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1]; wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename)+1); MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename)+1);
HRESULT hr = S_OK;
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
ComPtr<IMFSourceResolver> pSourceResolver = NULL; _ComPtr<IMFSourceResolver> pSourceResolver = NULL;
IUnknown* pUnkSource = NULL; IUnknown* pUnkSource = NULL;
hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf()); HRESULT hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -3714,10 +3952,10 @@ IplImage* CvCaptureFile_MSMF::retrieveFrame(int) ...@@ -3714,10 +3952,10 @@ IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource) HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
{ {
ComPtr<IMFPresentationDescriptor> pPD = NULL; _ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL; _ComPtr<IMFStreamDescriptor> pSD = NULL;
ComPtr<IMFMediaTypeHandler> pHandler = NULL; _ComPtr<IMFMediaTypeHandler> pHandler = NULL;
ComPtr<IMFMediaType> pType = NULL; _ComPtr<IMFMediaType> pType = NULL;
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf()); HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -3834,7 +4072,7 @@ private: ...@@ -3834,7 +4072,7 @@ private:
GUID inputFormat; GUID inputFormat;
DWORD streamIndex; DWORD streamIndex;
ComPtr<IMFSinkWriter> sinkWriter; _ComPtr<IMFSinkWriter> sinkWriter;
bool initiated; bool initiated;
...@@ -3874,8 +4112,10 @@ const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc) ...@@ -3874,8 +4112,10 @@ const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
return MFVideoFormat_DVSD; break; return MFVideoFormat_DVSD; break;
case CV_FOURCC_MACRO('d', 'v', 's', 'l'): case CV_FOURCC_MACRO('d', 'v', 's', 'l'):
return MFVideoFormat_DVSL; break; return MFVideoFormat_DVSL; break;
case CV_FOURCC_MACRO('H', '2', '6', '3'): #if (WINVER >= _WIN32_WINNT_WIN8)
case CV_FOURCC_MACRO('H', '2', '6', '3'): // Available only for Win 8 target.
return MFVideoFormat_H263; break; return MFVideoFormat_H263; break;
#endif
case CV_FOURCC_MACRO('H', '2', '6', '4'): case CV_FOURCC_MACRO('H', '2', '6', '4'):
return MFVideoFormat_H264; break; return MFVideoFormat_H264; break;
case CV_FOURCC_MACRO('M', '4', 'S', '2'): case CV_FOURCC_MACRO('M', '4', 'S', '2'):
...@@ -3985,10 +4225,10 @@ bool CvVideoWriter_MSMF::writeFrame(const IplImage* img) ...@@ -3985,10 +4225,10 @@ bool CvVideoWriter_MSMF::writeFrame(const IplImage* img)
HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename) HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
{ {
ComPtr<IMFAttributes> spAttr; _ComPtr<IMFAttributes> spAttr;
ComPtr<IMFMediaType> mediaTypeOut; _ComPtr<IMFMediaType> mediaTypeOut;
ComPtr<IMFMediaType> mediaTypeIn; _ComPtr<IMFMediaType> mediaTypeIn;
ComPtr<IMFByteStream> spByteStream; _ComPtr<IMFByteStream> spByteStream;
MFCreateAttributes(&spAttr, 10); MFCreateAttributes(&spAttr, 10);
spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true); spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
...@@ -4085,8 +4325,8 @@ HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename) ...@@ -4085,8 +4325,8 @@ HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
HRESULT CvVideoWriter_MSMF::WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& Start, const LONGLONG& Duration) HRESULT CvVideoWriter_MSMF::WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& Start, const LONGLONG& Duration)
{ {
ComPtr<IMFSample> sample; _ComPtr<IMFSample> sample;
ComPtr<IMFMediaBuffer> buffer; _ComPtr<IMFMediaBuffer> buffer;
const LONG cbWidth = 4 * videoWidth; const LONG cbWidth = 4 * videoWidth;
const DWORD cbBuffer = cbWidth * videoHeight; const DWORD cbBuffer = cbWidth * videoHeight;
......
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#define ICustomStreamSink StreamSink #define ICustomStreamSink StreamSink
#include "ppltasks_winrt.h" #ifndef __cplusplus_winrt
#define __is_winrt_array(type) (type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt8Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int16Array ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt16Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int32Array ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt32Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int64Array ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt64Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_SingleArray ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_DoubleArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_Char16Array ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_BooleanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_StringArray ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_InspectableArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_DateTimeArray ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_TimeSpanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_GuidArray ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_PointArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_SizeArray ||\
type == ABI::Windows::Foundation::PropertyType::PropertyType_RectArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray)
template<typename _Type, bool bUnknown = std::is_base_of<IUnknown, _Type>::value>
struct winrt_type
{
};
template<typename _Type>
struct winrt_type<_Type, true>
{
static IUnknown* create(_Type* _ObjInCtx) {
return reinterpret_cast<IUnknown*>(_ObjInCtx);
}
static IID getuuid() { return __uuidof(_Type); }
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
};
template <typename _Type>
struct winrt_type<_Type, false>
{
static IUnknown* create(_Type* _ObjInCtx) {
Microsoft::WRL::ComPtr<IInspectable> _PObj;
Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
if (FAILED(hr)) return nullptr;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
if (SUCCEEDED(hr))
hr = objFactory.As(&spPropVal);
if (SUCCEEDED(hr)) {
hr = winrt_type<_Type>::create(spPropVal.Get(), _ObjInCtx, _PObj.GetAddressOf());
if (SUCCEEDED(hr))
return reinterpret_cast<IUnknown*>(_PObj.Detach());
}
return nullptr;
}
static IID getuuid() { return __uuidof(ABI::Windows::Foundation::IPropertyValue); }
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
};
template<>
struct winrt_type<void>
{
static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, void* _ObjInCtx, IInspectable** ppInsp) {
(void)_ObjInCtx;
return spPropVal->CreateEmpty(ppInsp);
}
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
};
#define MAKE_TYPE(Type, Name) template<>\
struct winrt_type<Type>\
{\
static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, Type* _ObjInCtx, IInspectable** ppInsp) {\
return spPropVal->Create##Name(*_ObjInCtx, ppInsp);\
}\
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name;\
};
template<typename _Type>
struct winrt_array_type
{
static IUnknown* create(_Type* _ObjInCtx, size_t N) {
Microsoft::WRL::ComPtr<IInspectable> _PObj;
Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
if (FAILED(hr)) return nullptr;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
if (SUCCEEDED(hr))
hr = objFactory.As(&spPropVal);
if (SUCCEEDED(hr)) {
hr = winrt_array_type<_Type>::create(spPropVal.Get(), N, _ObjInCtx, _PObj.GetAddressOf());
if (SUCCEEDED(hr))
return reinterpret_cast<IUnknown*>(_PObj.Detach());
}
return nullptr;
}
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray;
};
template<int>
struct winrt_prop_type {};
template <>
struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_Empty> {
typedef void _Type;
};
template <>
struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherType> {
typedef void _Type;
};
template <>
struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherTypeArray> {
typedef void _Type;
};
#define MAKE_PROP(Prop, Type) template <>\
struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_##Prop> {\
typedef Type _Type;\
};
#define MAKE_ARRAY_TYPE(Type, Name) MAKE_PROP(Name, Type)\
MAKE_PROP(Name##Array, Type*)\
MAKE_TYPE(Type, Name)\
template<>\
struct winrt_array_type<Type*>\
{\
static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, Type** _ObjInCtx, IInspectable** ppInsp) {\
return spPropVal->Create##Name##Array(__valueSize, *_ObjInCtx, ppInsp);\
}\
static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name##Array;\
static std::vector<Type> PropertyValueToVector(ABI::Windows::Foundation::IPropertyValue* propValue)\
{\
UINT32 uLen = 0;\
Type* pArray = nullptr;\
propValue->Get##Name##Array(&uLen, &pArray);\
return std::vector<Type>(pArray, pArray + uLen);\
}\
};
MAKE_ARRAY_TYPE(BYTE, UInt8)
MAKE_ARRAY_TYPE(INT16, Int16)
MAKE_ARRAY_TYPE(UINT16, UInt16)
MAKE_ARRAY_TYPE(INT32, Int32)
MAKE_ARRAY_TYPE(UINT32, UInt32)
MAKE_ARRAY_TYPE(INT64, Int64)
MAKE_ARRAY_TYPE(UINT64, UInt64)
MAKE_ARRAY_TYPE(FLOAT, Single)
MAKE_ARRAY_TYPE(DOUBLE, Double)
MAKE_ARRAY_TYPE(WCHAR, Char16)
//MAKE_ARRAY_TYPE(boolean, Boolean) //conflict with identical type in C++ of BYTE/UInt8
MAKE_ARRAY_TYPE(HSTRING, String)
MAKE_ARRAY_TYPE(IInspectable*, Inspectable)
MAKE_ARRAY_TYPE(GUID, Guid)
MAKE_ARRAY_TYPE(ABI::Windows::Foundation::DateTime, DateTime)
MAKE_ARRAY_TYPE(ABI::Windows::Foundation::TimeSpan, TimeSpan)
MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Point, Point)
MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Size, Size)
MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Rect, Rect)
template < typename T >
struct DerefHelper
{
typedef T DerefType;
};
template < typename T >
struct DerefHelper<T*>
{
typedef T DerefType;
};
#define __is_valid_winrt_type(_Type) (std::is_void<_Type>::value || \
std::is_same<_Type, BYTE>::value || \
std::is_same<_Type, INT16>::value || \
std::is_same<_Type, UINT16>::value || \
std::is_same<_Type, INT32>::value || \
std::is_same<_Type, UINT32>::value || \
std::is_same<_Type, INT64>::value || \
std::is_same<_Type, UINT64>::value || \
std::is_same<_Type, FLOAT>::value || \
std::is_same<_Type, DOUBLE>::value || \
std::is_same<_Type, WCHAR>::value || \
std::is_same<_Type, boolean>::value || \
std::is_same<_Type, HSTRING>::value || \
std::is_same<_Type, IInspectable *>::value || \
std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, _Type>::value || \
std::is_base_of<IInspectable, typename DerefHelper<_Type>::DerefType>::value || \
std::is_same<_Type, GUID>::value || \
std::is_same<_Type, ABI::Windows::Foundation::DateTime>::value || \
std::is_same<_Type, ABI::Windows::Foundation::TimeSpan>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Point>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Size>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Rect>::value || \
std::is_same<_Type, BYTE*>::value || \
std::is_same<_Type, INT16*>::value || \
std::is_same<_Type, UINT16*>::value || \
std::is_same<_Type, INT32*>::value || \
std::is_same<_Type, UINT32*>::value || \
std::is_same<_Type, INT64*>::value || \
std::is_same<_Type, UINT64*>::value || \
std::is_same<_Type, FLOAT*>::value || \
std::is_same<_Type, DOUBLE*>::value || \
std::is_same<_Type, WCHAR*>::value || \
std::is_same<_Type, boolean*>::value || \
std::is_same<_Type, HSTRING*>::value || \
std::is_same<_Type, IInspectable **>::value || \
std::is_same<_Type, GUID*>::value || \
std::is_same<_Type, ABI::Windows::Foundation::DateTime*>::value || \
std::is_same<_Type, ABI::Windows::Foundation::TimeSpan*>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Point*>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Size*>::value || \
std::is_same<_Type, ABI::Windows::Foundation::Rect*>::value)
#endif
#else #else
EXTERN_C const IID IID_ICustomStreamSink; EXTERN_C const IID IID_ICustomStreamSink;
...@@ -178,12 +378,33 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP ...@@ -178,12 +378,33 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
#ifdef __cplusplus_winrt
#define _ContextCallback Concurrency::details::_ContextCallback
#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = S_OK;\
var._CallInContext([__VA_ARGS__]() {
#define END_CALL_IN_CONTEXT(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
});
#define END_CALL_IN_CONTEXT_BASE });
#else
#define _ContextCallback Concurrency_winrt::details::_ContextCallback
#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = var._CallInContext([__VA_ARGS__]() -> HRESULT {
#define END_CALL_IN_CONTEXT(hr) return hr;\
});
#define END_CALL_IN_CONTEXT_BASE return S_OK;\
});
#endif
#define GET_CURRENT_CONTEXT _ContextCallback::_CaptureCurrent()
#define SAVE_CURRENT_CONTEXT(var) _ContextCallback var = GET_CURRENT_CONTEXT
#define COMMA ,
#ifdef __cplusplus_winrt #ifdef __cplusplus_winrt
#define _Object Platform::Object^ #define _Object Platform::Object^
#define _ObjectObj Platform::Object^ #define _ObjectObj Platform::Object^
#define _String Platform::String^ #define _String Platform::String^
#define _StringObj Platform::String^ #define _StringObj Platform::String^
#define _StringReference ref new Platform::String #define _StringReference ref new Platform::String
#define _StringReferenceObj Platform::String^
#define _DeviceInformationCollection Windows::Devices::Enumeration::DeviceInformationCollection #define _DeviceInformationCollection Windows::Devices::Enumeration::DeviceInformationCollection
#define _MediaCapture Windows::Media::Capture::MediaCapture #define _MediaCapture Windows::Media::Capture::MediaCapture
#define _MediaCaptureVideoPreview Windows::Media::Capture::MediaCapture #define _MediaCaptureVideoPreview Windows::Media::Capture::MediaCapture
...@@ -193,6 +414,7 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP ...@@ -193,6 +414,7 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
#define _MediaEncodingProperties Windows::Media::MediaProperties::IMediaEncodingProperties #define _MediaEncodingProperties Windows::Media::MediaProperties::IMediaEncodingProperties
#define _VideoEncodingProperties Windows::Media::MediaProperties::VideoEncodingProperties #define _VideoEncodingProperties Windows::Media::MediaProperties::VideoEncodingProperties
#define _MediaStreamType Windows::Media::Capture::MediaStreamType #define _MediaStreamType Windows::Media::Capture::MediaStreamType
#define _AsyncInfo Windows::Foundation::IAsyncInfo
#define _AsyncAction Windows::Foundation::IAsyncAction #define _AsyncAction Windows::Foundation::IAsyncAction
#define _AsyncOperation Windows::Foundation::IAsyncOperation #define _AsyncOperation Windows::Foundation::IAsyncOperation
#define _DeviceClass Windows::Devices::Enumeration::DeviceClass #define _DeviceClass Windows::Devices::Enumeration::DeviceClass
...@@ -209,29 +431,37 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP ...@@ -209,29 +431,37 @@ MAKE_MAP(MFSTREAMSINK_MARKER_TYPE) StreamSinkMarkerTypeMap(StreamSinkMarkerTypeP
#define _InitializeWithSettingsAsync InitializeAsync #define _InitializeWithSettingsAsync InitializeAsync
#define _FindAllAsyncDeviceClass FindAllAsync #define _FindAllAsyncDeviceClass FindAllAsync
#define _MediaExtension Windows::Media::IMediaExtension #define _MediaExtension Windows::Media::IMediaExtension
#define _ContextCallback Concurrency::details::_ContextCallback #define BEGIN_CREATE_ASYNC(type, ...) (Concurrency::create_async([__VA_ARGS__]() {
#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = S_OK;\
var._CallInContext([__VA_ARGS__]() {
#define END_CALL_IN_CONTEXT(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
});
#define DO_ACTION_SYNCHRONOUSLY(hr, action, ctxt) hr = S_OK;\
CCompletionHandler::PerformActionSynchronously(reinterpret_cast<Windows::Foundation::IAsyncAction^>(action), ctxt)
#define DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, action, ctxt, pResult, vectortype, elementtype, _type) hr = S_OK;\
pResult = CCompletionHandler::PerformSynchronously<_type^>(reinterpret_cast<Windows::Foundation::IAsyncOperation<_type^>^>(action), ctxt)
#define BEGIN_CREATE_ASYNC(...) reinterpret_cast<ABI::Windows::Foundation::IAsyncAction*>(Concurrency::create_async([__VA_ARGS__]() {
#define END_CREATE_ASYNC(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\ #define END_CREATE_ASYNC(hr) if (FAILED(hr)) throw Platform::Exception::CreateException(hr);\
})) }))
#define DEFINE_TASK Concurrency::task #define DEFINE_TASK Concurrency::task
#define CREATE_TASK Concurrency::create_task #define CREATE_TASK Concurrency::create_task
#define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency::task<rettype>()) ? Concurrency::create_task(func) : _task.then([func](rettype) -> rettype { return func(); }); #define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency::task<rettype>()) ? Concurrency::create_task(func) : _task.then([func](rettype) -> rettype { return func(); });
#define DEFINE_RET_VAL(x)
#define DEFINE_RET_TYPE(x)
#define DEFINE_RET_FORMAL(x) x
#define RET_VAL(x) return x;
#define RET_VAL_BASE
#define MAKE_STRING(str) str
#define GET_STL_STRING(str) std::wstring(str->Data())
#define GET_STL_STRING_RAW(str) std::wstring(str->Data())
#define MAKE_WRL_OBJ(x) x^ #define MAKE_WRL_OBJ(x) x^
#define MAKE_WRL_REF(x) x^ #define MAKE_WRL_REF(x) x^
#define MAKE_OBJ_REF(x) x^
#define MAKE_WRL_AGILE_REF(x) Platform::Agile<x^> #define MAKE_WRL_AGILE_REF(x) Platform::Agile<x^>
#define MAKE_PROPERTY_BACKING(Type, PropName) property Type PropName;
#define MAKE_PROPERTY(Type, PropName, PropValue)
#define MAKE_PROPERTY_STRING(Type, PropName, PropValue)
#define MAKE_READONLY_PROPERTY(Type, PropName, PropValue) property Type PropName\
{\
Type get() { return PropValue; }\
}
#define THROW_INVALID_ARG throw ref new Platform::InvalidArgumentException();
#define RELEASE_AGILE_WRL(x) x = nullptr; #define RELEASE_AGILE_WRL(x) x = nullptr;
#define RELEASE_WRL(x) x = nullptr; #define RELEASE_WRL(x) x = nullptr;
#define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) objtype^ obj = orig;\ #define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) objtype^ obj = orig;\
hr = S_OK; hr = S_OK;
#define GET_WRL_OBJ_FROM_OBJ(objtype, obj, orig, hr) objtype^ obj = orig;\ #define GET_WRL_OBJ_FROM_OBJ(objtype, obj, orig, hr) objtype^ obj = safe_cast<objtype^>(orig);\
hr = S_OK; hr = S_OK;
#define WRL_ENUM_GET(obj, prefix, prop) obj::##prop #define WRL_ENUM_GET(obj, prefix, prop) obj::##prop
#define WRL_PROP_GET(obj, prop, arg, hr) arg = obj->##prop;\ #define WRL_PROP_GET(obj, prop, arg, hr) arg = obj->##prop;\
...@@ -242,11 +472,18 @@ hr = S_OK; ...@@ -242,11 +472,18 @@ hr = S_OK;
hr = S_OK; hr = S_OK;
#define WRL_METHOD(obj, method, ret, hr, ...) ret = obj->##method(__VA_ARGS__);\ #define WRL_METHOD(obj, method, ret, hr, ...) ret = obj->##method(__VA_ARGS__);\
hr = S_OK; hr = S_OK;
#define WRL_METHOD_NORET_BASE(obj, method, hr) obj->##method();\
hr = S_OK;
#define WRL_METHOD_NORET(obj, method, hr, ...) obj->##method(__VA_ARGS__);\
hr = S_OK;
#define REF_WRL_OBJ(obj) &obj #define REF_WRL_OBJ(obj) &obj
#define DEREF_WRL_OBJ(obj) obj #define DEREF_WRL_OBJ(obj) obj
#define DEREF_AGILE_WRL_OBJ(obj) obj.Get() #define DEREF_AGILE_WRL_OBJ(obj) obj.Get()
#define DEREF_AS_NATIVE_WRL_OBJ(type, obj) reinterpret_cast<type*>(obj) #define DEREF_AS_NATIVE_WRL_OBJ(type, obj) reinterpret_cast<type*>(obj)
#define PREPARE_TRANSFER_WRL_OBJ(obj) obj #define PREPARE_TRANSFER_WRL_OBJ(obj) obj
#define ACTIVATE_LOCAL_OBJ_BASE(objtype) ref new objtype()
#define ACTIVATE_LOCAL_OBJ(objtype, ...) ref new objtype(__VA_ARGS__)
#define ACTIVATE_EVENT_HANDLER(objtype, ...) ref new objtype(__VA_ARGS__)
#define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj = ref new objtype();\ #define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj = ref new objtype();\
hr = S_OK; hr = S_OK;
#define ACTIVATE_STATIC_OBJ(rtclass, objtype, obj, hr) objtype obj;\ #define ACTIVATE_STATIC_OBJ(rtclass, objtype, obj, hr) objtype obj;\
...@@ -257,6 +494,7 @@ hr = S_OK; ...@@ -257,6 +494,7 @@ hr = S_OK;
#define _String HSTRING #define _String HSTRING
#define _StringObj Microsoft::WRL::Wrappers::HString #define _StringObj Microsoft::WRL::Wrappers::HString
#define _StringReference Microsoft::WRL::Wrappers::HStringReference #define _StringReference Microsoft::WRL::Wrappers::HStringReference
#define _StringReferenceObj Microsoft::WRL::Wrappers::HStringReference
#define _DeviceInformationCollection ABI::Windows::Devices::Enumeration::DeviceInformationCollection #define _DeviceInformationCollection ABI::Windows::Devices::Enumeration::DeviceInformationCollection
#define _MediaCapture ABI::Windows::Media::Capture::IMediaCapture #define _MediaCapture ABI::Windows::Media::Capture::IMediaCapture
#define _MediaCaptureVideoPreview ABI::Windows::Media::Capture::IMediaCaptureVideoPreview #define _MediaCaptureVideoPreview ABI::Windows::Media::Capture::IMediaCaptureVideoPreview
...@@ -266,6 +504,7 @@ hr = S_OK; ...@@ -266,6 +504,7 @@ hr = S_OK;
#define _MediaEncodingProperties ABI::Windows::Media::MediaProperties::IMediaEncodingProperties #define _MediaEncodingProperties ABI::Windows::Media::MediaProperties::IMediaEncodingProperties
#define _VideoEncodingProperties ABI::Windows::Media::MediaProperties::IVideoEncodingProperties #define _VideoEncodingProperties ABI::Windows::Media::MediaProperties::IVideoEncodingProperties
#define _MediaStreamType ABI::Windows::Media::Capture::MediaStreamType #define _MediaStreamType ABI::Windows::Media::Capture::MediaStreamType
#define _AsyncInfo ABI::Windows::Foundation::IAsyncInfo
#define _AsyncAction ABI::Windows::Foundation::IAsyncAction #define _AsyncAction ABI::Windows::Foundation::IAsyncAction
#define _AsyncOperation ABI::Windows::Foundation::IAsyncOperation #define _AsyncOperation ABI::Windows::Foundation::IAsyncOperation
#define _DeviceClass ABI::Windows::Devices::Enumeration::DeviceClass #define _DeviceClass ABI::Windows::Devices::Enumeration::DeviceClass
...@@ -282,21 +521,32 @@ hr = S_OK; ...@@ -282,21 +521,32 @@ hr = S_OK;
#define _InitializeWithSettingsAsync InitializeWithSettingsAsync #define _InitializeWithSettingsAsync InitializeWithSettingsAsync
#define _FindAllAsyncDeviceClass FindAllAsyncDeviceClass #define _FindAllAsyncDeviceClass FindAllAsyncDeviceClass
#define _MediaExtension ABI::Windows::Media::IMediaExtension #define _MediaExtension ABI::Windows::Media::IMediaExtension
#define _ContextCallback Concurrency_winrt::details::_ContextCallback #define BEGIN_CREATE_ASYNC(type, ...) Concurrency_winrt::create_async<type>([__VA_ARGS__]() -> HRESULT {
#define BEGIN_CALL_IN_CONTEXT(hr, var, ...) hr = var._CallInContext([__VA_ARGS__]() -> HRESULT {
#define END_CALL_IN_CONTEXT(hr) return hr;\
});
#define DO_ACTION_SYNCHRONOUSLY(hr, action, ctxt) hr = CCompletionHandler<ABI::Windows::Foundation::IAsyncActionCompletedHandler, ABI::Windows::Foundation::IAsyncAction>::PerformActionSynchronously(action, ctxt)
#define DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, action, ctxt, pResult, vectortype, elementtype, _type) hr = CCompletionHandler<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_type*>, ABI::Windows::Foundation::IAsyncOperation<_type*>>::PerformSynchronously<vectortype<elementtype*>*>(action, ctxt, pResult.GetAddressOf())
#define BEGIN_CREATE_ASYNC(...) Concurrency_winrt::create_async([__VA_ARGS__]() -> HRESULT {
#define END_CREATE_ASYNC(hr) return hr;\ #define END_CREATE_ASYNC(hr) return hr;\
}) })
#define DEFINE_TASK Concurrency_winrt::task #define DEFINE_TASK Concurrency_winrt::task
#define CREATE_TASK Concurrency_winrt::create_task #define CREATE_TASK Concurrency_winrt::create_task
#define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency_winrt::task<rettype>()) ? Concurrency_winrt::create_task(func) : _task.then([func](rettype) -> rettype { return func(); }); #define CREATE_OR_CONTINUE_TASK(_task, rettype, func) _task = (_task == Concurrency_winrt::task<rettype>()) ? Concurrency_winrt::create_task<rettype>(func) : _task.then([func](rettype, rettype* retVal) -> HRESULT { return func(retVal); });
#define DEFINE_RET_VAL(x) x* retVal
#define DEFINE_RET_TYPE(x) <x>
#define DEFINE_RET_FORMAL(x) HRESULT
#define RET_VAL(x) *retVal = x;\
return S_OK;
#define RET_VAL_BASE return S_OK;
#define MAKE_STRING(str) Microsoft::WRL::Wrappers::HStringReference(L##str)
#define GET_STL_STRING(str) std::wstring(str.GetRawBuffer(NULL))
#define GET_STL_STRING_RAW(str) WindowsGetStringRawBuffer(str, NULL)
#define MAKE_WRL_OBJ(x) Microsoft::WRL::ComPtr<x> #define MAKE_WRL_OBJ(x) Microsoft::WRL::ComPtr<x>
#define MAKE_WRL_REF(x) x* #define MAKE_WRL_REF(x) x*
#define MAKE_OBJ_REF(x) x
#define MAKE_WRL_AGILE_REF(x) x* #define MAKE_WRL_AGILE_REF(x) x*
#define MAKE_PROPERTY_BACKING(Type, PropName) Type PropName;
#define MAKE_PROPERTY(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { *pVal = PropValue; } else { return E_INVALIDARG; } return S_OK; }\
STDMETHODIMP put_##PropName(Type Val) { PropValue = Val; return S_OK; }
#define MAKE_PROPERTY_STRING(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { return ::WindowsDuplicateString(PropValue.Get(), pVal); } else { return E_INVALIDARG; } }\
STDMETHODIMP put_##PropName(Type Val) { return PropValue.Set(Val); }
#define MAKE_READONLY_PROPERTY(Type, PropName, PropValue) STDMETHODIMP get_##PropName(Type* pVal) { if (pVal) { *pVal = PropValue; } else { return E_INVALIDARG; } return S_OK; }
#define THROW_INVALID_ARG RoOriginateError(E_INVALIDARG, nullptr);
#define RELEASE_AGILE_WRL(x) if (x) { (x)->Release(); x = nullptr; } #define RELEASE_AGILE_WRL(x) if (x) { (x)->Release(); x = nullptr; }
#define RELEASE_WRL(x) if (x) { (x)->Release(); x = nullptr; } #define RELEASE_WRL(x) if (x) { (x)->Release(); x = nullptr; }
#define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) Microsoft::WRL::ComPtr<objtype> obj;\ #define GET_WRL_OBJ_FROM_REF(objtype, obj, orig, hr) Microsoft::WRL::ComPtr<objtype> obj;\
...@@ -308,11 +558,15 @@ hr = orig.As(&obj); ...@@ -308,11 +558,15 @@ hr = orig.As(&obj);
#define WRL_PROP_PUT(obj, prop, arg, hr) hr = obj->put_##prop(arg); #define WRL_PROP_PUT(obj, prop, arg, hr) hr = obj->put_##prop(arg);
#define WRL_METHOD_BASE(obj, method, ret, hr) hr = obj->##method(&ret); #define WRL_METHOD_BASE(obj, method, ret, hr) hr = obj->##method(&ret);
#define WRL_METHOD(obj, method, ret, hr, ...) hr = obj->##method(__VA_ARGS__, &ret); #define WRL_METHOD(obj, method, ret, hr, ...) hr = obj->##method(__VA_ARGS__, &ret);
#define WRL_METHOD_NORET_BASE(obj, method, hr) hr = obj->##method();
#define REF_WRL_OBJ(obj) obj.GetAddressOf() #define REF_WRL_OBJ(obj) obj.GetAddressOf()
#define DEREF_WRL_OBJ(obj) obj.Get() #define DEREF_WRL_OBJ(obj) obj.Get()
#define DEREF_AGILE_WRL_OBJ(obj) obj #define DEREF_AGILE_WRL_OBJ(obj) obj
#define DEREF_AS_NATIVE_WRL_OBJ(type, obj) obj.Get() #define DEREF_AS_NATIVE_WRL_OBJ(type, obj) obj.Get()
#define PREPARE_TRANSFER_WRL_OBJ(obj) obj.Detach() #define PREPARE_TRANSFER_WRL_OBJ(obj) obj.Detach()
#define ACTIVATE_LOCAL_OBJ_BASE(objtype) Microsoft::WRL::Make<objtype>()
#define ACTIVATE_LOCAL_OBJ(objtype, ...) Microsoft::WRL::Make<objtype>(__VA_ARGS__)
#define ACTIVATE_EVENT_HANDLER(objtype, ...) Microsoft::WRL::Callback<objtype>(__VA_ARGS__).Get()
#define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj;\ #define ACTIVATE_OBJ(rtclass, objtype, obj, hr) MAKE_WRL_OBJ(objtype) obj;\
{\ {\
Microsoft::WRL::ComPtr<IActivationFactory> objFactory;\ Microsoft::WRL::ComPtr<IActivationFactory> objFactory;\
...@@ -333,272 +587,96 @@ hr = orig.As(&obj); ...@@ -333,272 +587,96 @@ hr = orig.As(&obj);
} }
#endif #endif
#define GET_CURRENT_CONTEXT _ContextCallback::_CaptureCurrent() #define _ComPtr Microsoft::WRL::ComPtr
#define SAVE_CURRENT_CONTEXT(var) _ContextCallback var = GET_CURRENT_CONTEXT
#ifdef __cplusplus_winrt
ref class CCompletionHandler sealed
#else #else
template <typename TCompletionHandler, typename TAction>
class CCompletionHandler template <class T>
: public Microsoft::WRL::RuntimeClass< class ComPtr : public ATL::CComPtr<T>
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::ClassicCom>,
TCompletionHandler, IAgileObject, FtmBase>
#endif
{ {
MixInHelper()
#ifndef __cplusplus_winrt
public: public:
CCompletionHandler() {} ComPtr() throw()
STDMETHODIMP Invoke(TAction* /*asyncInfo*/, AsyncStatus /*asyncStatus*/)
{ {
m_Event.set();
return S_OK;
} }
void wait() { m_Event.wait(); } ComPtr(int nNull) throw() :
#endif CComPtr<T>((T*)nNull)
#ifdef __cplusplus_winrt
internal:
template <typename TResult>
static TResult PerformSynchronously(Windows::Foundation::IAsyncOperation<TResult>^ asyncOp, _ContextCallback context)
{
TResult pResult;
context._CallInContext([asyncOp, &pResult]() { Concurrency::task<TResult> asyncTask = Concurrency::task<TResult>(asyncOp); pResult = asyncTask.get(); });
return pResult;
#else
template <typename TResult>
static HRESULT PerformSynchronously(TAction* asyncOp, _ContextCallback context, TResult* pResult)
{ {
HRESULT hr;
ComPtr<CCompletionHandler<TCompletionHandler, TAction>> completeHandler = Microsoft::WRL::Make<CCompletionHandler<TCompletionHandler, TAction>>();
hr = context._CallInContext([&asyncOp, &completeHandler]() -> HRESULT {
HRESULT hr = asyncOp->put_Completed(completeHandler.Get());
if (FAILED(hr)) asyncOp->Release();
return hr;
});
if (SUCCEEDED(hr))
completeHandler->wait();
else
return hr;
hr = context._CallInContext([&asyncOp, &pResult]() -> HRESULT {
HRESULT hr = asyncOp->GetResults(pResult);
asyncOp->Release();
return hr;
});
return hr;
#endif
} }
ComPtr(T* lp) throw() :
CComPtr<T>(lp)
#ifdef __cplusplus_winrt
static void PerformActionSynchronously(Windows::Foundation::IAsyncAction^ asyncOp, _ContextCallback context)
{ {
context._CallInContext([asyncOp](){ Concurrency::task<void>(asyncOp).get(); }); }
#else ComPtr(_In_ const CComPtr<T>& lp) throw() :
static HRESULT PerformActionSynchronously(TAction* asyncOp, _ContextCallback context) CComPtr<T>(lp.p)
{ {
HRESULT hr;
ComPtr<CCompletionHandler<TCompletionHandler, TAction>> completeHandler = Microsoft::WRL::Make<CCompletionHandler<TCompletionHandler, TAction>>();
hr = context._CallInContext([&asyncOp, &completeHandler]() -> HRESULT {
HRESULT hr = asyncOp->put_Completed(completeHandler.Get());
if (FAILED(hr)) asyncOp->Release();
return hr;
});
if (SUCCEEDED(hr))
completeHandler->wait();
else
return hr;
hr = context._CallInContext([&asyncOp]() -> HRESULT {
HRESULT hr = asyncOp->GetResults();
asyncOp->Release();
return hr;
});
return hr;
#endif
} }
#ifndef __cplusplus_winrt virtual ~ComPtr() {}
private:
Concurrency::event m_Event;
#endif
};
#ifndef __cplusplus_winrt
// Helpers for create_async validation
//
// A parameter lambda taking no arguments is valid
template<typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int) -> typename decltype(_Param(), std::true_type());
// A parameter lambda taking an cancellation_token argument is valid
template<typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(cancellation_token::none()), std::true_type());
// A parameter lambda taking a progress report argument is valid
template<typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type());
// A parameter lambda taking a progress report and a cancellation_token argument is valid T* const* GetAddressOf() const throw()
template<typename _Ty>
static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), cancellation_token::none()), std::true_type());
// All else is invalid
template<typename _Ty>
static std::false_type _IsValidCreateAsync(_Ty _Param, ...);
//for task specific architecture
//could add a CancelPending which is set when Cancel is called, return as Cancel when get_Status is called and set when a task_canceled exception is thrown
extern const __declspec(selectany) WCHAR RuntimeClass_CV_CAsyncAction[] = L"cv.CAsyncAction";
template<typename _Function>
class CAsyncAction
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>,
Microsoft::WRL::Implements<ABI::Windows::Foundation::IAsyncAction>, Microsoft::WRL::AsyncBase<ABI::Windows::Foundation::IAsyncActionCompletedHandler >>
{
InspectableClass(RuntimeClass_CV_CAsyncAction, BaseTrust)
public:
STDMETHOD(RuntimeClassInitialize)() { return S_OK; }
virtual ~CAsyncAction() {}
CAsyncAction(const _Function &_Func) : _M_func(_Func) {
Start();
}
void _SetTaskCreationAddressHint(void* _SourceAddressHint)
{
if (!(std::is_same<Concurrency_winrt::details::_TaskTypeTraits<Concurrency_winrt::task<HRESULT>>::_AsyncKind, Concurrency_winrt::details::_TypeSelectorAsyncTask>::value))
{ {
// Overwrite the creation address with the return address of create_async unless the return &p;
// lambda returned a task. If the create async lambda returns a task, that task is reused and
// we want to preserve its creation address hint.
_M_task._SetTaskCreationAddressHint(_SourceAddressHint);
}
} }
HRESULT STDMETHODCALLTYPE put_Completed(
/* [in] */ __RPC__in_opt ABI::Windows::Foundation::IAsyncActionCompletedHandler *handler) T** GetAddressOf() throw()
{ {
HRESULT hr; return &p;
if (SUCCEEDED(hr = PutOnComplete(handler)) && cCallbackMade_ == 0) {
//okay to use default implementation even for the callback as already running in context
//otherwise check for the alternate case and save the context
_M_completeDelegateContext = _ContextCallback::_CaptureCurrent();
}
return hr;
}
HRESULT STDMETHODCALLTYPE get_Completed(
/* [out][retval] */ __RPC__deref_out_opt ABI::Windows::Foundation::IAsyncActionCompletedHandler **handler) {
if (!handler) return E_POINTER;
return GetOnComplete(handler);
}
HRESULT STDMETHODCALLTYPE GetResults(void) {
HRESULT hr = CheckValidStateForResultsCall();
if (SUCCEEDED(hr)) {
_M_task.get();
} }
return hr;
} T** ReleaseAndGetAddressOf() throw()
HRESULT OnStart() { {
_M_task = Concurrency_winrt::task<HRESULT>(_M_func, _M_cts.get_token()); InternalRelease();
AddRef(); return &p;
_M_task.then([this](Concurrency_winrt::task<HRESULT> _Antecedent) {
try {
HRESULT hr = _Antecedent.get();
if (FAILED(hr)) TryTransitionToError(hr);
} }
catch (Concurrency::task_canceled&){
T* Get() const throw()
{
return p;
} }
catch (...) { ComPtr& operator=(decltype(__nullptr)) throw()
TryTransitionToError(E_FAIL); {
InternalRelease();
return *this;
} }
_FireCompletion(); ComPtr& operator=(_In_ const int nNull) throw()
Release(); {
}); ASSERT(nNull == 0);
return S_OK; (void)nNull;
InternalRelease();
return *this;
} }
void OnClose() {} unsigned long Reset()
void OnCancel() { _M_cts.cancel(); }
protected:
//modified for _CallInContext to support UI STA thread
//can wrap the base clase implementation or duplicate it but must use get_Completed to fetch the private member variable
virtual void _FireCompletion()
{ {
AddRef(); return InternalRelease();
_M_completeDelegateContext._CallInContext([this]() -> HRESULT {
FireCompletion();
Release();
return S_OK;
});
} }
private: // query for U interface
template<typename U>
_Function _M_func; HRESULT As(_Inout_ U** lp) const throw()
Concurrency_winrt::task<HRESULT> _M_task;
Concurrency::cancellation_token_source _M_cts;
_ContextCallback _M_completeDelegateContext;
};
template<typename _Function>
__declspec(noinline)
CAsyncAction<_Function>* create_async(const _Function& _Func)
{
static_assert(std::is_same<decltype(_IsValidCreateAsync(_Func, 0, 0, 0, 0)), std::true_type>::value,
"argument to create_async must be a callable object taking zero, one or two arguments");
CAsyncAction<_Function>* action = Microsoft::WRL::Make<CAsyncAction<_Function>>(_Func).Detach();
action->_SetTaskCreationAddressHint(_ReturnAddress());
return action;
}
#endif
EXTERN_C const IID IID_IMedCapFailHandler;
class DECLSPEC_UUID("CE22BEDB-0B3C-4BE0-BE8F-E53AB457EA2C") DECLSPEC_NOVTABLE IMedCapFailHandler : public IUnknown
{
public:
virtual HRESULT AddHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap) = 0;
virtual HRESULT RemoveHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap) = 0;
};
template<typename _Function>
class MediaCaptureFailedHandler :
public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::ClassicCom>,
IMedCapFailHandler, ABI::Windows::Media::Capture::IMediaCaptureFailedEventHandler, IAgileObject, FtmBase>
{
public:
MediaCaptureFailedHandler(const _Function &_Func) : _M_func(_Func) { m_cookie.value = 0; }
HRESULT AddHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap)
{ {
return pMedCap->add_Failed(this, &m_cookie); return p->QueryInterface(__uuidof(U), (void**)lp);
} }
HRESULT RemoveHandler(ABI::Windows::Media::Capture::IMediaCapture* pMedCap) // query for U interface
template<typename U>
HRESULT As(_Out_ ComPtr<U>* lp) const throw()
{ {
return pMedCap->remove_Failed(m_cookie); return p->QueryInterface(__uuidof(U), reinterpret_cast<void**>(lp->ReleaseAndGetAddressOf()));
} }
HRESULT STDMETHODCALLTYPE Invoke( private:
ABI::Windows::Media::Capture::IMediaCapture *sender, unsigned long InternalRelease() throw()
ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs *errorEventArgs)
{ {
(void)sender; unsigned long ref = 0;
(void)errorEventArgs; T* temp = p;
AddRef();
_M_func(); if (temp != nullptr)
Release(); {
return S_OK; p = nullptr;
ref = temp->Release();
} }
private: return ref;
_Function _M_func; }
EventRegistrationToken m_cookie;
}; };
template<typename _Function> #define _ComPtr ComPtr
__declspec(noinline)
MediaCaptureFailedHandler<_Function>* create_medcapfailedhandler(const _Function& _Func)
{
return Microsoft::WRL::Make<MediaCaptureFailedHandler<_Function>>(_Func).Detach();
}
#endif #endif
template <class TBase=IMFAttributes> template <class TBase=IMFAttributes>
...@@ -946,7 +1024,7 @@ done: ...@@ -946,7 +1024,7 @@ done:
} }
protected: protected:
ComPtr<IMFAttributes> _spAttributes; _ComPtr<IMFAttributes> _spAttributes;
}; };
class StreamSink : class StreamSink :
...@@ -1005,11 +1083,11 @@ public: ...@@ -1005,11 +1083,11 @@ public:
#ifdef HAVE_WINRT #ifdef HAVE_WINRT
STDMETHOD(RuntimeClassInitialize)() { return S_OK; } STDMETHOD(RuntimeClassInitialize)() { return S_OK; }
#else #else
ULONG AddRef() ULONG STDMETHODCALLTYPE AddRef()
{ {
return InterlockedIncrement(&m_cRef); return InterlockedIncrement(&m_cRef);
} }
ULONG Release() ULONG STDMETHODCALLTYPE Release()
{ {
ULONG cRef = InterlockedDecrement(&m_cRef); ULONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0) if (cRef == 0)
...@@ -1025,7 +1103,7 @@ public: ...@@ -1025,7 +1103,7 @@ public:
if (m_spFTM == nullptr) { if (m_spFTM == nullptr) {
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
if (m_spFTM == nullptr) { if (m_spFTM == nullptr) {
hr = CoCreateFreeThreadedMarshaler(static_cast<IMFStreamSink*>(this), &m_spFTM); hr = CoCreateFreeThreadedMarshaler((IMFStreamSink*)this, &m_spFTM);
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
} }
...@@ -1061,14 +1139,12 @@ public: ...@@ -1061,14 +1139,12 @@ public:
InitializeCriticalSectionEx(&m_critSec, 3000, 0); InitializeCriticalSectionEx(&m_critSec, 3000, 0);
ZeroMemory(&m_guiCurrentSubtype, sizeof(m_guiCurrentSubtype)); ZeroMemory(&m_guiCurrentSubtype, sizeof(m_guiCurrentSubtype));
CBaseAttributes::Initialize(0U); CBaseAttributes::Initialize(0U);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::StreamSink\n");
DPO->printOut(L"StreamSink::StreamSink\n");
} }
virtual ~StreamSink() { virtual ~StreamSink() {
DeleteCriticalSection(&m_critSec); DeleteCriticalSection(&m_critSec);
assert(m_IsShutdown); assert(m_IsShutdown);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::~StreamSink\n");
DPO->printOut(L"StreamSink::~StreamSink\n");
} }
HRESULT Initialize() HRESULT Initialize()
...@@ -1078,7 +1154,7 @@ public: ...@@ -1078,7 +1154,7 @@ public:
hr = MFCreateEventQueue(&m_spEventQueue); hr = MFCreateEventQueue(&m_spEventQueue);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IMFMediaSink> pMedSink; _ComPtr<IMFMediaSink> pMedSink;
hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf()); hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf());
assert(pMedSink.Get() != NULL); assert(pMedSink.Get() != NULL);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
...@@ -1102,10 +1178,8 @@ public: ...@@ -1102,10 +1178,8 @@ public:
// Called when the presentation clock starts. // Called when the presentation clock starts.
HRESULT Start(MFTIME start) HRESULT Start(MFTIME start)
{ {
EnterCriticalSection(&m_critSec);
HRESULT hr = S_OK; HRESULT hr = S_OK;
EnterCriticalSection(&m_critSec);
if (m_state != State_TypeNotSet) { if (m_state != State_TypeNotSet) {
if (start != PRESENTATION_CURRENT_POSITION) if (start != PRESENTATION_CURRENT_POSITION)
{ {
...@@ -1184,7 +1258,7 @@ public: ...@@ -1184,7 +1258,7 @@ public:
// Shuts down the stream sink. // Shuts down the stream sink.
HRESULT Shutdown() HRESULT Shutdown()
{ {
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
HRESULT hr = S_OK; HRESULT hr = S_OK;
assert(!m_IsShutdown); assert(!m_IsShutdown);
hr = m_pParent->GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = m_pParent->GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
...@@ -1217,7 +1291,7 @@ public: ...@@ -1217,7 +1291,7 @@ public:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IMFMediaSink> pMedSink; _ComPtr<IMFMediaSink> pMedSink;
hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf()); hr = CBaseAttributes<>::GetUnknown(MF_STREAMSINK_MEDIASINKINTERFACE, __uuidof(IMFMediaSink), (LPVOID*)pMedSink.GetAddressOf());
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
*ppMediaSink = pMedSink.Detach(); *ppMediaSink = pMedSink.Detach();
...@@ -1225,8 +1299,7 @@ public: ...@@ -1225,8 +1299,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetMediaSink: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetMediaSink: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1247,8 +1320,7 @@ public: ...@@ -1247,8 +1320,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetIdentifier: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetIdentifier: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1270,14 +1342,13 @@ public: ...@@ -1270,14 +1342,13 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetMediaTypeHandler: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetMediaTypeHandler: HRESULT=%i\n", hr);
return hr; return hr;
} }
HRESULT STDMETHODCALLTYPE ProcessSample(IMFSample *pSample) { HRESULT STDMETHODCALLTYPE ProcessSample(IMFSample *pSample) {
ComPtr<IMFMediaBuffer> pInput; _ComPtr<IMFMediaBuffer> pInput;
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
BYTE *pSrc = NULL; // Source buffer. BYTE *pSrc = NULL; // Source buffer.
// Stride if the buffer does not support IMF2DBuffer // Stride if the buffer does not support IMF2DBuffer
LONGLONG hnsTime = 0; LONGLONG hnsTime = 0;
...@@ -1334,6 +1405,7 @@ public: ...@@ -1334,6 +1405,7 @@ public:
/* [in] */ MFSTREAMSINK_MARKER_TYPE eMarkerType, /* [in] */ MFSTREAMSINK_MARKER_TYPE eMarkerType,
/* [in] */ __RPC__in const PROPVARIANT * /*pvarMarkerValue*/, /* [in] */ __RPC__in const PROPVARIANT * /*pvarMarkerValue*/,
/* [in] */ __RPC__in const PROPVARIANT * /*pvarContextValue*/) { /* [in] */ __RPC__in const PROPVARIANT * /*pvarContextValue*/) {
eMarkerType;
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
HRESULT hr = S_OK; HRESULT hr = S_OK;
...@@ -1345,12 +1417,12 @@ public: ...@@ -1345,12 +1417,12 @@ public:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
//at shutdown will receive MFSTREAMSINK_MARKER_ENDOFSEGMENT
hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL); hr = QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::PlaceMarker: HRESULT=%i %s\n", hr, StreamSinkMarkerTypeMap.at(eMarkerType).c_str());
DPO->printOut(L"StreamSink::PlaceMarker: HRESULT=%i %s\n", hr, StreamSinkMarkerTypeMap.at(eMarkerType).c_str());
return hr; return hr;
} }
...@@ -1364,8 +1436,7 @@ public: ...@@ -1364,8 +1436,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::Flush: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::Flush: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1378,7 +1449,7 @@ public: ...@@ -1378,7 +1449,7 @@ public:
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<IMFMediaEventQueue> pQueue; _ComPtr<IMFMediaEventQueue> pQueue;
{ {
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
...@@ -1403,13 +1474,12 @@ public: ...@@ -1403,13 +1474,12 @@ public:
if (SUCCEEDED(hr) && SUCCEEDED((*ppEvent)->GetType(&meType)) && meType == MEStreamSinkStopped) { if (SUCCEEDED(hr) && SUCCEEDED((*ppEvent)->GetType(&meType)) && meType == MEStreamSinkStopped) {
} }
HRESULT hrStatus = S_OK; HRESULT hrStatus = S_OK;
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = (*ppEvent)->GetStatus(&hrStatus); hr = (*ppEvent)->GetStatus(&hrStatus);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
DPO->printOut(L"StreamSink::GetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str()); DebugPrintOut(L"StreamSink::GetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
else else
DPO->printOut(L"StreamSink::GetEvent: HRESULT=%i\n", hr); DebugPrintOut(L"StreamSink::GetEvent: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1426,8 +1496,7 @@ public: ...@@ -1426,8 +1496,7 @@ public:
hr = m_spEventQueue->BeginGetEvent(pCallback, punkState); hr = m_spEventQueue->BeginGetEvent(pCallback, punkState);
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::BeginGetEvent: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::BeginGetEvent: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1449,14 +1518,13 @@ public: ...@@ -1449,14 +1518,13 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
HRESULT hrStatus = S_OK; HRESULT hrStatus = S_OK;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = (*ppEvent)->GetStatus(&hrStatus); hr = (*ppEvent)->GetStatus(&hrStatus);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
DPO->printOut(L"StreamSink::EndGetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str()); DebugPrintOut(L"StreamSink::EndGetEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(meType).c_str());
else else
DPO->printOut(L"StreamSink::EndGetEvent: HRESULT=%i\n", hr); DebugPrintOut(L"StreamSink::EndGetEvent: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1475,9 +1543,8 @@ public: ...@@ -1475,9 +1543,8 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::QueueEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(met).c_str());
DPO->printOut(L"StreamSink::QueueEvent: HRESULT=%i %s\n", hrStatus, MediaEventTypeMap.at(met).c_str()); DebugPrintOut(L"StreamSink::QueueEvent: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::QueueEvent: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1522,13 +1589,14 @@ public: ...@@ -1522,13 +1589,14 @@ public:
hr = MF_E_INVALIDTYPE; hr = MF_E_INVALIDTYPE;
} }
} }
// We don't return any "close match" types.
if (ppMediaType) if (ppMediaType)
{ {
*ppMediaType = nullptr; *ppMediaType = nullptr;
} }
if (ppMediaType && SUCCEEDED(hr)) { if (ppMediaType && SUCCEEDED(hr)) {
ComPtr<IMFMediaType> pType; _ComPtr<IMFMediaType> pType;
hr = MFCreateMediaType(ppMediaType); hr = MFCreateMediaType(ppMediaType);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType); hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
...@@ -1558,8 +1626,7 @@ public: ...@@ -1558,8 +1626,7 @@ public:
} }
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::IsMediaTypeSupported: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::IsMediaTypeSupported: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1583,8 +1650,7 @@ public: ...@@ -1583,8 +1650,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetMediaTypeCount: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetMediaTypeCount: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1609,7 +1675,7 @@ public: ...@@ -1609,7 +1675,7 @@ public:
//return preferred type based on media capture library 6 elements preferred preview type //return preferred type based on media capture library 6 elements preferred preview type
//hr = m_spCurrentType.CopyTo(ppType); //hr = m_spCurrentType.CopyTo(ppType);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
ComPtr<IMFMediaType> pType; _ComPtr<IMFMediaType> pType;
hr = MFCreateMediaType(ppType); hr = MFCreateMediaType(ppType);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType); hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
...@@ -1641,8 +1707,7 @@ public: ...@@ -1641,8 +1707,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetMediaTypeByIndex: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetMediaTypeByIndex: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1674,9 +1739,6 @@ public: ...@@ -1674,9 +1739,6 @@ public:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
GUID guiMajorType;
pMediaType->GetMajorType(&guiMajorType);
hr = MFCreateMediaType(m_spCurrentType.ReleaseAndGetAddressOf()); hr = MFCreateMediaType(m_spCurrentType.ReleaseAndGetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -1686,7 +1748,11 @@ public: ...@@ -1686,7 +1748,11 @@ public:
{ {
hr = m_spCurrentType->GetGUID(MF_MT_SUBTYPE, &m_guiCurrentSubtype); hr = m_spCurrentType->GetGUID(MF_MT_SUBTYPE, &m_guiCurrentSubtype);
} }
GUID guid;
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = m_spCurrentType->GetMajorType(&guid);
}
if (SUCCEEDED(hr) && guid == MFMediaType_Video) {
hr = MFGetAttributeSize(m_spCurrentType.Get(), MF_MT_FRAME_SIZE, &m_imageWidthInPixels, &m_imageHeightInPixels); hr = MFGetAttributeSize(m_spCurrentType.Get(), MF_MT_FRAME_SIZE, &m_imageWidthInPixels, &m_imageHeightInPixels);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
...@@ -1696,8 +1762,7 @@ public: ...@@ -1696,8 +1762,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::SetCurrentMediaType: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::SetCurrentMediaType: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1723,8 +1788,7 @@ public: ...@@ -1723,8 +1788,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetCurrentMediaType: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetCurrentMediaType: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -1737,13 +1801,12 @@ public: ...@@ -1737,13 +1801,12 @@ public:
return E_INVALIDARG; return E_INVALIDARG;
} }
ComPtr<IMFMediaType> pType; _ComPtr<IMFMediaType> pType;
hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType); hr = m_pParent->GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)&pType);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = pType->GetMajorType(pguidMajorType); hr = pType->GetMajorType(pguidMajorType);
} }
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"StreamSink::GetMajorType: HRESULT=%i\n", hr);
DPO->printOut(L"StreamSink::GetMajorType: HRESULT=%i\n", hr);
return hr; return hr;
} }
private: private:
...@@ -1759,10 +1822,10 @@ private: ...@@ -1759,10 +1822,10 @@ private:
long m_cRef; long m_cRef;
#endif #endif
IMFAttributes* m_pParent; IMFAttributes* m_pParent;
ComPtr<IMFMediaType> m_spCurrentType; _ComPtr<IMFMediaType> m_spCurrentType;
ComPtr<IMFMediaEventQueue> m_spEventQueue; // Event queue _ComPtr<IMFMediaEventQueue> m_spEventQueue; // Event queue
ComPtr<IUnknown> m_spFTM; _ComPtr<IUnknown> m_spFTM;
State m_state; State m_state;
bool m_fGetStartTimeFromSample; bool m_fGetStartTimeFromSample;
bool m_fWaitingForFirstSample; bool m_fWaitingForFirstSample;
...@@ -2296,7 +2359,7 @@ class MediaSink : ...@@ -2296,7 +2359,7 @@ class MediaSink :
Microsoft::WRL::Implements<ABI::Windows::Media::IMediaExtension>, Microsoft::WRL::Implements<ABI::Windows::Media::IMediaExtension>,
IMFMediaSink, IMFMediaSink,
IMFClockStateSink, IMFClockStateSink,
FtmBase, Microsoft::WRL::FtmBase,
CBaseAttributes<>> CBaseAttributes<>>
#else #else
public IMFMediaSink, public IMFClockStateSink, public CBaseAttributes<> public IMFMediaSink, public IMFClockStateSink, public CBaseAttributes<>
...@@ -2307,11 +2370,11 @@ class MediaSink : ...@@ -2307,11 +2370,11 @@ class MediaSink :
public: public:
#else #else
public: public:
ULONG AddRef() ULONG STDMETHODCALLTYPE AddRef()
{ {
return InterlockedIncrement(&m_cRef); return InterlockedIncrement(&m_cRef);
} }
ULONG Release() ULONG STDMETHODCALLTYPE Release()
{ {
ULONG cRef = InterlockedDecrement(&m_cRef); ULONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0) if (cRef == 0)
...@@ -2347,13 +2410,11 @@ public: ...@@ -2347,13 +2410,11 @@ public:
MediaSink() : m_IsShutdown(false), m_llStartTime(0) { MediaSink() : m_IsShutdown(false), m_llStartTime(0) {
CBaseAttributes<>::Initialize(0U); CBaseAttributes<>::Initialize(0U);
InitializeCriticalSectionEx(&m_critSec, 3000, 0); InitializeCriticalSectionEx(&m_critSec, 3000, 0);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::MediaSink\n");
DPO->printOut(L"MediaSink::MediaSink\n");
} }
virtual ~MediaSink() { virtual ~MediaSink() {
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::~MediaSink\n");
DPO->printOut(L"MediaSink::~MediaSink\n");
DeleteCriticalSection(&m_critSec); DeleteCriticalSection(&m_critSec);
assert(m_IsShutdown); assert(m_IsShutdown);
} }
...@@ -2376,7 +2437,7 @@ public: ...@@ -2376,7 +2437,7 @@ public:
Microsoft::WRL::ComPtr<IInspectable> spInsp; Microsoft::WRL::ComPtr<IInspectable> spInsp;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> spSetting; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> spSetting;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropVal; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropVal;
ComPtr<ABI::Windows::Media::MediaProperties::IMediaEncodingProperties> pMedEncProps; Microsoft::WRL::ComPtr<ABI::Windows::Media::MediaProperties::IMediaEncodingProperties> pMedEncProps;
UINT32 uiType = ABI::Windows::Media::Capture::MediaStreamType_VideoPreview; UINT32 uiType = ABI::Windows::Media::Capture::MediaStreamType_VideoPreview;
hr = pConfiguration->QueryInterface(IID_PPV_ARGS(&spSetting)); hr = pConfiguration->QueryInterface(IID_PPV_ARGS(&spSetting));
...@@ -2385,7 +2446,7 @@ public: ...@@ -2385,7 +2446,7 @@ public:
} }
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = spSetting->Lookup(HStringReference(MF_PROP_SAMPLEGRABBERCALLBACK).Get(), spInsp.ReleaseAndGetAddressOf()); hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_SAMPLEGRABBERCALLBACK).Get(), spInsp.ReleaseAndGetAddressOf());
if (FAILED(hr)) { if (FAILED(hr)) {
hr = E_INVALIDARG; hr = E_INVALIDARG;
} }
...@@ -2394,7 +2455,7 @@ public: ...@@ -2394,7 +2455,7 @@ public:
} }
} }
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = spSetting->Lookup(HStringReference(MF_PROP_VIDTYPE).Get(), spInsp.ReleaseAndGetAddressOf()); hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_VIDTYPE).Get(), spInsp.ReleaseAndGetAddressOf());
if (FAILED(hr)) { if (FAILED(hr)) {
hr = E_INVALIDARG; hr = E_INVALIDARG;
} }
...@@ -2405,7 +2466,7 @@ public: ...@@ -2405,7 +2466,7 @@ public:
} }
} }
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = spSetting->Lookup(HStringReference(MF_PROP_VIDENCPROPS).Get(), spInsp.ReleaseAndGetAddressOf()); hr = spSetting->Lookup(Microsoft::WRL::Wrappers::HStringReference(MF_PROP_VIDENCPROPS).Get(), spInsp.ReleaseAndGetAddressOf());
if (FAILED(hr)) { if (FAILED(hr)) {
hr = E_INVALIDARG; hr = E_INVALIDARG;
} }
...@@ -2480,14 +2541,13 @@ public: ...@@ -2480,14 +2541,13 @@ public:
case ABI::Windows::Foundation::PropertyType_String: case ABI::Windows::Foundation::PropertyType_String:
{ {
HSTRING value; Microsoft::WRL::Wrappers::HString value;
hr = pValue->GetString(&value); hr = pValue->GetString(value.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
UINT32 len = 0; UINT32 len = 0;
LPCWSTR szValue = WindowsGetStringRawBuffer(value, &len); LPCWSTR szValue = WindowsGetStringRawBuffer(value.Get(), &len);
hr = pAttr->SetString(guidKey, szValue); hr = pAttr->SetString(guidKey, szValue);
WindowsDeleteString(value);
} }
} }
break; break;
...@@ -2516,7 +2576,7 @@ public: ...@@ -2516,7 +2576,7 @@ public:
case ABI::Windows::Foundation::PropertyType_Inspectable: case ABI::Windows::Foundation::PropertyType_Inspectable:
{ {
ComPtr<IInspectable> value; Microsoft::WRL::ComPtr<IInspectable> value;
hr = TYPE_E_TYPEMISMATCH; hr = TYPE_E_TYPEMISMATCH;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -2534,10 +2594,10 @@ public: ...@@ -2534,10 +2594,10 @@ public:
static HRESULT ConvertPropertiesToMediaType(_In_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *pMEP, _Outptr_ IMFMediaType **ppMT) static HRESULT ConvertPropertiesToMediaType(_In_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *pMEP, _Outptr_ IMFMediaType **ppMT)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<IMFMediaType> spMT; _ComPtr<IMFMediaType> spMT;
ComPtr<ABI::Windows::Foundation::Collections::IMap<GUID, IInspectable*>> spMap; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<GUID, IInspectable*>> spMap;
ComPtr<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterable; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterable;
ComPtr<ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterator; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*>*>> spIterator;
if (pMEP == nullptr || ppMT == nullptr) if (pMEP == nullptr || ppMT == nullptr)
{ {
...@@ -2545,7 +2605,7 @@ public: ...@@ -2545,7 +2605,7 @@ public:
} }
*ppMT = nullptr; *ppMT = nullptr;
hr = pMEP->get_Properties(&spMap); hr = pMEP->get_Properties(spMap.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -2568,9 +2628,9 @@ public: ...@@ -2568,9 +2628,9 @@ public:
while (hasCurrent) while (hasCurrent)
{ {
ComPtr<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*> > spKeyValuePair; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IKeyValuePair<GUID, IInspectable*> > spKeyValuePair;
ComPtr<IInspectable> spValue; Microsoft::WRL::ComPtr<IInspectable> spValue;
ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
GUID guidKey; GUID guidKey;
hr = spIterator->get_Current(&spKeyValuePair); hr = spIterator->get_Current(&spKeyValuePair);
...@@ -2609,8 +2669,8 @@ public: ...@@ -2609,8 +2669,8 @@ public:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IInspectable> spValue; Microsoft::WRL::ComPtr<IInspectable> spValue;
ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue; Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValue> spPropValue;
GUID guiMajorType; GUID guiMajorType;
hr = spMap->Lookup(MF_MT_MAJOR_TYPE, spValue.GetAddressOf()); hr = spMap->Lookup(MF_MT_MAJOR_TYPE, spValue.GetAddressOf());
...@@ -2639,12 +2699,12 @@ public: ...@@ -2639,12 +2699,12 @@ public:
return hr; return hr;
} }
HRESULT SetMediaStreamProperties( //this should be passed through SetProperties!
ABI::Windows::Media::Capture::MediaStreamType MediaStreamType, HRESULT SetMediaStreamProperties(ABI::Windows::Media::Capture::MediaStreamType MediaStreamType,
_In_opt_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *mediaEncodingProperties) _In_opt_ ABI::Windows::Media::MediaProperties::IMediaEncodingProperties *mediaEncodingProperties)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<IMFMediaType> spMediaType; _ComPtr<IMFMediaType> spMediaType;
if (MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoPreview && if (MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoPreview &&
MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoRecord && MediaStreamType != ABI::Windows::Media::Capture::MediaStreamType_VideoRecord &&
...@@ -2657,7 +2717,7 @@ public: ...@@ -2657,7 +2717,7 @@ public:
if (mediaEncodingProperties != nullptr) if (mediaEncodingProperties != nullptr)
{ {
ComPtr<IMFStreamSink> spStreamSink; _ComPtr<IMFStreamSink> spStreamSink;
hr = ConvertPropertiesToMediaType(mediaEncodingProperties, &spMediaType); hr = ConvertPropertiesToMediaType(mediaEncodingProperties, &spMediaType);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -2678,18 +2738,18 @@ public: ...@@ -2678,18 +2738,18 @@ public:
if (pdwCharacteristics == NULL) return E_INVALIDARG; if (pdwCharacteristics == NULL) return E_INVALIDARG;
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
if (SUCCEEDED(hr = CheckShutdown())) { if (SUCCEEDED(hr = CheckShutdown())) {
*pdwCharacteristics = MEDIASINK_FIXED_STREAMS; //if had an activation object for the sink, shut down would be managed and MF_STREAM_SINK_SUPPORTS_ROTATION appears to be setable to TRUE
*pdwCharacteristics = MEDIASINK_FIXED_STREAMS;// | MEDIASINK_REQUIRE_REFERENCE_MEDIATYPE;
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::GetCharacteristics: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::GetCharacteristics: HRESULT=%i\n", hr); return hr;
return S_OK;
} }
HRESULT STDMETHODCALLTYPE AddStreamSink( HRESULT STDMETHODCALLTYPE AddStreamSink(
DWORD dwStreamSinkIdentifier, IMFMediaType * /*pMediaType*/, IMFStreamSink **ppStreamSink) { DWORD dwStreamSinkIdentifier, IMFMediaType * /*pMediaType*/, IMFStreamSink **ppStreamSink) {
ComPtr<IMFStreamSink> spMFStream; _ComPtr<IMFStreamSink> spMFStream;
ComPtr<ICustomStreamSink> pStream; _ComPtr<ICustomStreamSink> pStream;
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
HRESULT hr = CheckShutdown(); HRESULT hr = CheckShutdown();
...@@ -2729,7 +2789,7 @@ public: ...@@ -2729,7 +2789,7 @@ public:
} }
// Initialize the stream. // Initialize the stream.
ComPtr<IMFAttributes> pAttr; _ComPtr<IMFAttributes> pAttr;
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = pStream.As(&pAttr); hr = pStream.As(&pAttr);
} }
...@@ -2752,7 +2812,7 @@ public: ...@@ -2752,7 +2812,7 @@ public:
for (; pos != posEnd; pos = m_streams.Next(pos)) for (; pos != posEnd; pos = m_streams.Next(pos))
{ {
DWORD dwCurrId; DWORD dwCurrId;
ComPtr<IMFStreamSink> spCurr; _ComPtr<IMFStreamSink> spCurr;
hr = m_streams.GetItemPos(pos, &spCurr); hr = m_streams.GetItemPos(pos, &spCurr);
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -2781,8 +2841,7 @@ public: ...@@ -2781,8 +2841,7 @@ public:
*ppStreamSink = spMFStream.Detach(); *ppStreamSink = spMFStream.Detach();
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::AddStreamSink: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::AddStreamSink: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -2791,7 +2850,7 @@ public: ...@@ -2791,7 +2850,7 @@ public:
HRESULT hr = CheckShutdown(); HRESULT hr = CheckShutdown();
ComPtrList<IMFStreamSink>::POSITION pos = m_streams.FrontPosition(); ComPtrList<IMFStreamSink>::POSITION pos = m_streams.FrontPosition();
ComPtrList<IMFStreamSink>::POSITION endPos = m_streams.EndPosition(); ComPtrList<IMFStreamSink>::POSITION endPos = m_streams.EndPosition();
ComPtr<IMFStreamSink> spStream; _ComPtr<IMFStreamSink> spStream;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -2821,11 +2880,18 @@ public: ...@@ -2821,11 +2880,18 @@ public:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = m_streams.Remove(pos, nullptr); hr = m_streams.Remove(pos, nullptr);
static_cast<StreamSink *>(spStream.Get())->Shutdown(); _ComPtr<ICustomStreamSink> spCustomSink;
#ifdef HAVE_WINRT
spCustomSink = static_cast<StreamSink*>(spStream.Get());
hr = S_OK;
#else
hr = spStream.As(&spCustomSink);
#endif
if (SUCCEEDED(hr))
hr = spCustomSink->Shutdown();
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::RemoveStreamSink: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::RemoveStreamSink: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -2845,8 +2911,7 @@ public: ...@@ -2845,8 +2911,7 @@ public:
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::GetStreamSinkCount: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::GetStreamSinkCount: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -2857,7 +2922,7 @@ public: ...@@ -2857,7 +2922,7 @@ public:
return E_INVALIDARG; return E_INVALIDARG;
} }
ComPtr<IMFStreamSink> spStream; _ComPtr<IMFStreamSink> spStream;
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
DWORD cStreams = m_streams.GetCount(); DWORD cStreams = m_streams.GetCount();
...@@ -2894,8 +2959,7 @@ public: ...@@ -2894,8 +2959,7 @@ public:
*ppStreamSink = spStream.Detach(); *ppStreamSink = spStream.Detach();
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::GetStreamSinkByIndex: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::GetStreamSinkByIndex: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -2908,7 +2972,7 @@ public: ...@@ -2908,7 +2972,7 @@ public:
EnterCriticalSection(&m_critSec); EnterCriticalSection(&m_critSec);
HRESULT hr = CheckShutdown(); HRESULT hr = CheckShutdown();
ComPtr<IMFStreamSink> spResult; _ComPtr<IMFStreamSink> spResult;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
...@@ -2917,7 +2981,7 @@ public: ...@@ -2917,7 +2981,7 @@ public:
for (; pos != endPos; pos = m_streams.Next(pos)) for (; pos != endPos; pos = m_streams.Next(pos))
{ {
ComPtr<IMFStreamSink> spStream; _ComPtr<IMFStreamSink> spStream;
hr = m_streams.GetItemPos(pos, &spStream); hr = m_streams.GetItemPos(pos, &spStream);
DWORD dwId; DWORD dwId;
...@@ -2950,8 +3014,7 @@ public: ...@@ -2950,8 +3014,7 @@ public:
*ppStreamSink = spResult.Detach(); *ppStreamSink = spResult.Detach();
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::GetStreamSinkById: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::GetStreamSinkById: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -2976,7 +3039,7 @@ public: ...@@ -2976,7 +3039,7 @@ public:
} }
} }
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
// Release the pointer to the old clock. // Release the pointer to the old clock.
// Store the pointer to the new clock. // Store the pointer to the new clock.
...@@ -2986,8 +3049,7 @@ public: ...@@ -2986,8 +3049,7 @@ public:
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnSetPresentationClock(pPresentationClock); hr = pSampleCallback->OnSetPresentationClock(pPresentationClock);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::SetPresentationClock: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::SetPresentationClock: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -3010,8 +3072,7 @@ public: ...@@ -3010,8 +3072,7 @@ public:
} }
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::GetPresentationClock: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::GetPresentationClock: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -3025,13 +3086,16 @@ public: ...@@ -3025,13 +3086,16 @@ public:
m_streams.Clear(); m_streams.Clear();
m_spClock.ReleaseAndGetAddressOf(); m_spClock.ReleaseAndGetAddressOf();
_ComPtr<IMFMediaType> pType;
hr = CBaseAttributes<>::GetUnknown(MF_MEDIASINK_PREFERREDTYPE, __uuidof(IMFMediaType), (LPVOID*)pType.GetAddressOf());
if (SUCCEEDED(hr)) {
hr = DeleteItem(MF_MEDIASINK_PREFERREDTYPE); hr = DeleteItem(MF_MEDIASINK_PREFERREDTYPE);
}
m_IsShutdown = true; m_IsShutdown = true;
} }
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::Shutdown: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::Shutdown: HRESULT=%i\n", hr);
return hr; return hr;
} }
class ShutdownFunc class ShutdownFunc
...@@ -3039,8 +3103,16 @@ public: ...@@ -3039,8 +3103,16 @@ public:
public: public:
HRESULT operator()(IMFStreamSink *pStream) const HRESULT operator()(IMFStreamSink *pStream) const
{ {
static_cast<StreamSink *>(pStream)->Shutdown(); _ComPtr<ICustomStreamSink> spCustomSink;
return S_OK; HRESULT hr;
#ifdef HAVE_WINRT
spCustomSink = static_cast<StreamSink*>(pStream);
#else
hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
if (FAILED(hr)) return hr;
#endif
hr = spCustomSink->Shutdown();
return hr;
} }
}; };
...@@ -3054,7 +3126,16 @@ public: ...@@ -3054,7 +3126,16 @@ public:
HRESULT operator()(IMFStreamSink *pStream) const HRESULT operator()(IMFStreamSink *pStream) const
{ {
return static_cast<StreamSink *>(pStream)->Start(_llStartTime); _ComPtr<ICustomStreamSink> spCustomSink;
HRESULT hr;
#ifdef HAVE_WINRT
spCustomSink = static_cast<StreamSink*>(pStream);
#else
hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
if (FAILED(hr)) return hr;
#endif
hr = spCustomSink->Start(_llStartTime);
return hr;
} }
LONGLONG _llStartTime; LONGLONG _llStartTime;
...@@ -3065,7 +3146,16 @@ public: ...@@ -3065,7 +3146,16 @@ public:
public: public:
HRESULT operator()(IMFStreamSink *pStream) const HRESULT operator()(IMFStreamSink *pStream) const
{ {
return static_cast<StreamSink *>(pStream)->Stop(); _ComPtr<ICustomStreamSink> spCustomSink;
HRESULT hr;
#ifdef HAVE_WINRT
spCustomSink = static_cast<StreamSink*>(pStream);
#else
hr = pStream->QueryInterface(IID_PPV_ARGS(spCustomSink.GetAddressOf()));
if (FAILED(hr)) return hr;
#endif
hr = spCustomSink->Stop();
return hr;
} }
}; };
...@@ -3078,7 +3168,7 @@ public: ...@@ -3078,7 +3168,7 @@ public:
for (; pos != endPos; pos = col.Next(pos)) for (; pos != endPos; pos = col.Next(pos))
{ {
ComPtr<T> spStream; _ComPtr<T> spStream;
hr = col.GetItemPos(pos, &spStream); hr = col.GetItemPos(pos, &spStream);
if (FAILED(hr)) if (FAILED(hr))
...@@ -3104,14 +3194,13 @@ public: ...@@ -3104,14 +3194,13 @@ public:
m_llStartTime = llClockStartOffset; m_llStartTime = llClockStartOffset;
hr = ForEach(m_streams, StartFunc(llClockStartOffset)); hr = ForEach(m_streams, StartFunc(llClockStartOffset));
} }
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnClockStart(hnsSystemTime, llClockStartOffset); hr = pSampleCallback->OnClockStart(hnsSystemTime, llClockStartOffset);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::OnClockStart: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::OnClockStart: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -3125,38 +3214,35 @@ public: ...@@ -3125,38 +3214,35 @@ public:
// Stop each stream // Stop each stream
hr = ForEach(m_streams, StopFunc()); hr = ForEach(m_streams, StopFunc());
} }
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
LeaveCriticalSection(&m_critSec); LeaveCriticalSection(&m_critSec);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnClockStop(hnsSystemTime); hr = pSampleCallback->OnClockStop(hnsSystemTime);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::OnClockStop: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::OnClockStop: HRESULT=%i\n", hr);
return hr; return hr;
} }
HRESULT STDMETHODCALLTYPE OnClockPause( HRESULT STDMETHODCALLTYPE OnClockPause(
MFTIME hnsSystemTime) { MFTIME hnsSystemTime) {
HRESULT hr; HRESULT hr;
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnClockPause(hnsSystemTime); hr = pSampleCallback->OnClockPause(hnsSystemTime);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::OnClockPause: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::OnClockPause: HRESULT=%i\n", hr);
return hr; return hr;
} }
HRESULT STDMETHODCALLTYPE OnClockRestart( HRESULT STDMETHODCALLTYPE OnClockRestart(
MFTIME hnsSystemTime) { MFTIME hnsSystemTime) {
HRESULT hr; HRESULT hr;
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnClockRestart(hnsSystemTime); hr = pSampleCallback->OnClockRestart(hnsSystemTime);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::OnClockRestart: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::OnClockRestart: HRESULT=%i\n", hr);
return hr; return hr;
} }
...@@ -3164,12 +3250,11 @@ public: ...@@ -3164,12 +3250,11 @@ public:
MFTIME hnsSystemTime, MFTIME hnsSystemTime,
float flRate) { float flRate) {
HRESULT hr; HRESULT hr;
ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback; _ComPtr<IMFSampleGrabberSinkCallback> pSampleCallback;
hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf()); hr = GetUnknown(MF_MEDIASINK_SAMPLEGRABBERCALLBACK, IID_IMFSampleGrabberSinkCallback, (LPVOID*)pSampleCallback.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
hr = pSampleCallback->OnClockSetRate(hnsSystemTime, flRate); hr = pSampleCallback->OnClockSetRate(hnsSystemTime, flRate);
DebugPrintOut *DPO = &DebugPrintOut::getInstance(); DebugPrintOut(L"MediaSink::OnClockSetRate: HRESULT=%i\n", hr);
DPO->printOut(L"MediaSink::OnClockSetRate: HRESULT=%i\n", hr);
return hr; return hr;
} }
private: private:
...@@ -3179,7 +3264,7 @@ private: ...@@ -3179,7 +3264,7 @@ private:
CRITICAL_SECTION m_critSec; CRITICAL_SECTION m_critSec;
bool m_IsShutdown; bool m_IsShutdown;
ComPtrList<IMFStreamSink> m_streams; ComPtrList<IMFStreamSink> m_streams;
ComPtr<IMFPresentationClock> m_spClock; _ComPtr<IMFPresentationClock> m_spClock;
LONGLONG m_llStartTime; LONGLONG m_llStartTime;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment