Commit eb41a574 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #4005 from MSOpenTech:videoio-contrib

parents a85bb091 3d20157d
...@@ -45,6 +45,24 @@ endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES Window ...@@ -45,6 +45,24 @@ endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES Window
if(WINRT) if(WINRT)
add_definitions(-DWINRT -DNO_GETENV) add_definitions(-DWINRT -DNO_GETENV)
# Making definitions available to other configurations and
# to filter dependency restrictions at compile time.
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone)
set(WINRT_PHONE TRUE)
add_definitions(-DWINRT_PHONE)
elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(WINRT_STORE TRUE)
add_definitions(-DWINRT_STORE)
endif()
if(CMAKE_SYSTEM_VERSION MATCHES 8.1)
set(WINRT_8_1 TRUE)
add_definitions(-DWINRT_8_1)
elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0)
set(WINRT_8_0 TRUE)
add_definitions(-DWINRT_8_0)
endif()
endif() endif()
if(POLICY CMP0022) if(POLICY CMP0022)
......
if(WINRT)
ocv_module_disable(videoio)
endif()
set(the_description "Media I/O") set(the_description "Media I/O")
ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidcamera WRAP java python) ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidcamera WRAP java python)
...@@ -11,7 +7,7 @@ ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidca ...@@ -11,7 +7,7 @@ ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidca
# Jose Luis Blanco, 2008 # Jose Luis Blanco, 2008
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if(HAVE_WINRT_CX AND NOT WINRT) if(WINRT_8_1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW")
endif() endif()
...@@ -36,6 +32,36 @@ file(GLOB videoio_ext_hdrs ...@@ -36,6 +32,36 @@ file(GLOB videoio_ext_hdrs
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h") "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h")
# Removing WinRT API headers by default
status(" ${name}: Removing WinRT API headers by default")
list(REMOVE_ITEM videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/cap_winrt.hpp")
# Dependencies used by the implementation referenced
# below are not available on WinRT 8.0.
# Enabling it for WiRT 8.1+ only.
if(DEFINED WINRT AND NOT DEFINED WINRT_8_0)
# WinRT detected. Adding WinRT API header
status(" ${name}: WinRT detected. Adding WinRT API header")
list(APPEND videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/cap_winrt.hpp")
# Adding WinRT internal sources and headers
list(APPEND videoio_srcs
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_capture.cpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_bridge.cpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_video.cpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/CaptureFrameGrabber.cpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaStreamSink.cpp)
list(APPEND videoio_hdrs
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_capture.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_bridge.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_video.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MFIncludes.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/CaptureFrameGrabber.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaSink.hpp
${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaStreamSink.hpp)
endif()
if(WIN32 AND NOT ARM) if(WIN32 AND NOT ARM)
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_cmu.cpp) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_cmu.cpp)
endif() endif()
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
@{ @{
@defgroup videoio_c C API @defgroup videoio_c C API
@defgroup videoio_ios iOS glue @defgroup videoio_ios iOS glue
@defgroup videoio_winrt WinRT glue
@} @}
*/ */
...@@ -85,6 +86,7 @@ enum { CAP_ANY = 0, // autodetect ...@@ -85,6 +86,7 @@ enum { CAP_ANY = 0, // autodetect
CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API) CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API)
CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK
CAP_MSMF = 1400, // Microsoft Media Foundation (via videoInput) CAP_MSMF = 1400, // Microsoft Media Foundation (via videoInput)
CAP_WINRT = 1410, // Microsoft Windows Runtime using Media Foundation
CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK
CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect)
CAP_OPENNI2_ASUS = 1610 // OpenNI2 (for Asus Xtion and Occipital Structure sensors) CAP_OPENNI2_ASUS = 1610 // OpenNI2 (for Asus Xtion and Occipital Structure sensors)
......
// Video support for Windows Runtime
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <ppl.h>
#include <functional>
#include <concrt.h>
#include <agile.h>
using namespace Windows::UI::Xaml::Controls;
namespace cv
{
//! @addtogroup videoio_winrt
//! @{
enum {
OPEN_CAMERA = 300,
CLOSE_CAMERA,
UPDATE_IMAGE_ELEMENT,
SHOW_TRACKBAR
};
/********************************** WinRT API ************************************************/
template <typename ...Args>
CV_EXPORTS void winrt_startMessageLoop(std::function<void(Args...)>&& callback, Args... args);
template <typename ...Args>
CV_EXPORTS void winrt_startMessageLoop(void callback(Args...), Args... args);
/** @brief
@note
Sets the reporter method for the HighguiAssist singleton. Starts the main OpenCV as
an async thread in WinRT. See VideoCapture for the example of callback implementation.
Here is how the class can be used:
@code
void cvMain()
{
Mat frame;
VideoCapture cam;
cam.open(0);
while (1)
{
cam >> frame;
// don't reprocess the same frame again
if (!cam.grab()) continue;
// your processing logic goes here
// obligatory step to get XAML image component updated
winrt_imshow();
}
}
MainPage::MainPage()
{
InitializeComponent();
cv::winrt_setFrameContainer(cvImage);
cv::winrt_startMessageLoop(cvMain);
}
@endcode
*/
template
CV_EXPORTS void winrt_startMessageLoop(void callback(void));
/** @brief
@note
Must be called from WinRT specific callback to handle image grabber state.
Here is how the class can be used:
@code
MainPage::MainPage()
{
// ...
Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &Application::MainPage::OnVisibilityChanged);
// ...
}
void Application::MainPage::OnVisibilityChanged(Platform::Object ^sender,
Windows::UI::Core::VisibilityChangedEventArgs ^e)
{
cv::winrt_onVisibilityChanged(e->Visible);
}
@endcode
*/
CV_EXPORTS void winrt_onVisibilityChanged(bool visible);
/** @brief
@note
Must be called to assign WinRT control holding image you're working with.
Code sample is available for winrt_startMessageLoop().
*/
CV_EXPORTS void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image);
/** @brief
@note
Must be called to update attached image source.
Code sample is available for winrt_startMessageLoop().
*/
CV_EXPORTS void winrt_imshow();
//! @} videoio_winrt
} // cv
\ No newline at end of file
This diff is collapsed.
...@@ -43,6 +43,13 @@ ...@@ -43,6 +43,13 @@
#include "cap_intelperc.hpp" #include "cap_intelperc.hpp"
#include "cap_dshow.hpp" #include "cap_dshow.hpp"
// All WinRT versions older than 8.0 should provide classes used for video support
#if defined(WINRT) && !defined(WINRT_8_0)
# include "cap_winrt_capture.hpp"
# include "cap_winrt_bridge.hpp"
# define WINRT_VIDEO
#endif
#if defined _M_X64 && defined _MSC_VER && !defined CV_ICC #if defined _M_X64 && defined _MSC_VER && !defined CV_ICC
#pragma optimize("",off) #pragma optimize("",off)
#pragma warning(disable: 4748) #pragma warning(disable: 4748)
...@@ -508,6 +515,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index) ...@@ -508,6 +515,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
#endif #endif
#ifdef HAVE_INTELPERC #ifdef HAVE_INTELPERC
CV_CAP_INTELPERC, CV_CAP_INTELPERC,
#endif
#ifdef WINRT_VIDEO
CAP_WINRT,
#endif #endif
-1, -1 -1, -1
}; };
...@@ -526,6 +536,7 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index) ...@@ -526,6 +536,7 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
{ {
#if defined(HAVE_DSHOW) || \ #if defined(HAVE_DSHOW) || \
defined(HAVE_INTELPERC) || \ defined(HAVE_INTELPERC) || \
defined(WINRT_VIDEO) || \
(0) (0)
Ptr<IVideoCapture> capture; Ptr<IVideoCapture> capture;
...@@ -540,6 +551,13 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index) ...@@ -540,6 +551,13 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
case CV_CAP_INTELPERC: case CV_CAP_INTELPERC:
capture = makePtr<VideoCapture_IntelPerC>(); capture = makePtr<VideoCapture_IntelPerC>();
break; // CV_CAP_INTEL_PERC break; // CV_CAP_INTEL_PERC
#endif
#ifdef WINRT_VIDEO
case CAP_WINRT:
capture = Ptr<IVideoCapture>(new cv::VideoCapture_WinRT(index));
if (capture)
return capture;
break; // CAP_WINRT
#endif #endif
} }
if (capture && capture->isOpened()) if (capture && capture->isOpened())
...@@ -664,7 +682,29 @@ bool VideoCapture::read(OutputArray image) ...@@ -664,7 +682,29 @@ bool VideoCapture::read(OutputArray image)
VideoCapture& VideoCapture::operator >> (Mat& image) VideoCapture& VideoCapture::operator >> (Mat& image)
{ {
#ifdef WINRT_VIDEO
if (grab())
{
if (retrieve(image))
{
std::lock_guard<std::mutex> lock(VideoioBridge::getInstance().inputBufferMutex);
VideoioBridge& bridge = VideoioBridge::getInstance();
// double buffering
bridge.swapInputBuffers();
auto p = bridge.frontInputPtr;
bridge.bIsFrameNew = false;
// needed here because setting Mat 'image' is not allowed by OutputArray in read()
Mat m(bridge.height, bridge.width, CV_8UC3, p);
image = m;
}
}
#else
read(image); read(image);
#endif
return *this; return *this;
} }
......
// Copyright (c) Microsoft. All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "MediaStreamSink.hpp"
#include "MediaSink.hpp"
#include "CaptureFrameGrabber.hpp"
using namespace Media;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Media;
using namespace Windows::Media::Capture;
using namespace Windows::Media::MediaProperties;
using namespace concurrency;
using namespace Microsoft::WRL::Details;
using namespace Microsoft::WRL;
task<Media::CaptureFrameGrabber^> Media::CaptureFrameGrabber::CreateAsync(_In_ MediaCapture^ capture, _In_ VideoEncodingProperties^ props, CaptureStreamType streamType)
{
auto reader = ref new Media::CaptureFrameGrabber(capture, props, streamType);
auto profile = ref new MediaEncodingProfile();
profile->Video = props;
task<void> task;
if (reader->_streamType == CaptureStreamType::Preview)
{
task = create_task(capture->StartPreviewToCustomSinkAsync(profile, reader->_mediaExtension));
}
else
{
task = create_task(capture->StartRecordToCustomSinkAsync(profile, reader->_mediaExtension));
}
return task.then([reader]()
{
reader->_state = State::Started;
return reader;
});
}
Media::CaptureFrameGrabber::CaptureFrameGrabber(_In_ MediaCapture^ capture, _In_ VideoEncodingProperties^ props, CaptureStreamType streamType)
: _state(State::Created)
, _streamType(streamType)
, _capture(capture)
{
auto videoSampleHandler = ref new MediaSampleHandler(this, &Media::CaptureFrameGrabber::ProcessSample);
_mediaSink = Make<MediaSink>(nullptr, props, nullptr, videoSampleHandler);
_mediaExtension = reinterpret_cast<IMediaExtension^>(static_cast<AWM::IMediaExtension*>(_mediaSink.Get()));
}
Media::CaptureFrameGrabber::~CaptureFrameGrabber()
{
if (_state == State::Started)
{
if (_streamType == CaptureStreamType::Preview)
{
(void)_capture->StopPreviewAsync();
}
else
{
(void)_capture->StopRecordAsync();
}
}
if (_mediaSink != nullptr)
{
(void)_mediaSink->Shutdown();
_mediaSink = nullptr;
}
_mediaExtension = nullptr;
_capture = nullptr;
}
void Media::CaptureFrameGrabber::ShowCameraSettings()
{
#if WINAPI_FAMILY!=WINAPI_FAMILY_PHONE_APP
if (_state == State::Started)
{
CameraOptionsUI::Show(_capture.Get());
}
#endif
}
task<void> Media::CaptureFrameGrabber::FinishAsync()
{
auto lock = _lock.LockExclusive();
if (_state != State::Started)
{
throw ref new COMException(E_UNEXPECTED, L"State");
}
_state = State::Closing;
if (_mediaSink != nullptr)
{
(void)_mediaSink->Shutdown();
_mediaSink = nullptr;
}
_mediaExtension = nullptr;
task<void> task;
if (_streamType == CaptureStreamType::Preview)
{
task = create_task(_capture->StopPreviewAsync());
}
else
{
task = create_task(_capture->StopRecordAsync());
}
return task.then([this]()
{
auto lock = _lock.LockExclusive();
_state = State::Closed;
_capture = nullptr;
});
}
task<ComPtr<IMF2DBuffer2>> Media::CaptureFrameGrabber::GetFrameAsync()
{
auto lock = _lock.LockExclusive();
if (_state != State::Started)
{
throw ref new COMException(E_UNEXPECTED, L"State");
}
_mediaSink->RequestVideoSample();
task_completion_event<ComPtr<IMF2DBuffer2>> taskEvent;
_videoSampleRequestQueue.push(taskEvent);
return create_task(taskEvent);
}
void Media::CaptureFrameGrabber::ProcessSample(_In_ MediaSample^ sample)
{
task_completion_event<ComPtr<IMF2DBuffer2>> t;
{
auto lock = _lock.LockExclusive();
t = _videoSampleRequestQueue.front();
_videoSampleRequestQueue.pop();
}
ComPtr<IMFMediaBuffer> buffer;
CHK(sample->Sample->ConvertToContiguousBuffer(&buffer));
// Dispatch without the lock taken to avoid deadlocks
t.set(As<IMF2DBuffer2>(buffer));
}
\ No newline at end of file
// Copyright (c) Microsoft. All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include "MFIncludes.hpp"
namespace Media {
class MediaSink;
enum class CaptureStreamType
{
Preview = 0,
Record
};
ref class CaptureFrameGrabber sealed
{
public:
// IClosable
virtual ~CaptureFrameGrabber();
virtual void ShowCameraSettings();
internal:
static concurrency::task<CaptureFrameGrabber^> CreateAsync(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props)
{
return CreateAsync(capture, props, CaptureStreamType::Preview);
}
static concurrency::task<CaptureFrameGrabber^> CreateAsync(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props, CaptureStreamType streamType);
concurrency::task<MW::ComPtr<IMF2DBuffer2>> GetFrameAsync();
concurrency::task<void> FinishAsync();
private:
CaptureFrameGrabber(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props, CaptureStreamType streamType);
void ProcessSample(_In_ MediaSample^ sample);
Platform::Agile<WMC::MediaCapture> _capture;
::Windows::Media::IMediaExtension^ _mediaExtension;
MW::ComPtr<MediaSink> _mediaSink;
CaptureStreamType _streamType;
enum class State
{
Created,
Started,
Closing,
Closed
} _state;
std::queue<concurrency::task_completion_event<MW::ComPtr<IMF2DBuffer2>>> _videoSampleRequestQueue;
AutoMF _mf;
MWW::SRWLock _lock;
};
}
\ No newline at end of file
// Header for standard system include files.
// Copyright (c) Microsoft. All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include <collection.h>
#include <ppltasks.h>
#include <wrl\implements.h>
#include <wrl\wrappers\corewrappers.h>
#include <Roerrorapi.h>
#include <queue>
#include <sstream>
#include <robuffer.h>
#include <mfapi.h>
#include <mfidl.h>
#include <Mferror.h>
#include <windows.media.h>
#include <windows.media.mediaproperties.h>
namespace AWM = ::ABI::Windows::Media;
namespace AWMMp = ::ABI::Windows::Media::MediaProperties;
namespace AWFC = ::ABI::Windows::Foundation::Collections;
namespace MW = ::Microsoft::WRL;
namespace MWD = ::Microsoft::WRL::Details;
namespace MWW = ::Microsoft::WRL::Wrappers;
namespace WMC = ::Windows::Media::Capture;
namespace WF = ::Windows::Foundation;
namespace WMMp = ::Windows::Media::MediaProperties;
namespace WSS = ::Windows::Storage::Streams;
// Exception-based error handling
#define CHK(statement) {HRESULT _hr = (statement); if (FAILED(_hr)) { throw ref new Platform::COMException(_hr); };}
#define CHKNULL(p) {if ((p) == nullptr) { throw ref new Platform::NullReferenceException(L#p); };}
// Exception-free error handling
#define CHK_RETURN(statement) {hr = (statement); if (FAILED(hr)) { return hr; };}
// Cast a C++/CX msartpointer to an ABI smartpointer
template<typename T, typename U>
MW::ComPtr<T> As(U^ in)
{
MW::ComPtr<T> out;
CHK(reinterpret_cast<IInspectable*>(in)->QueryInterface(IID_PPV_ARGS(&out)));
return out;
}
// Cast an ABI smartpointer
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> As(const Microsoft::WRL::ComPtr<U>& in)
{
Microsoft::WRL::ComPtr<T> out;
CHK(in.As(&out));
return out;
}
// Cast an ABI smartpointer
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> As(U* in)
{
Microsoft::WRL::ComPtr<T> out;
CHK(in->QueryInterface(IID_PPV_ARGS(&out)));
return out;
}
// Get access to bytes in IBuffer
inline unsigned char* GetData(_In_ WSS::IBuffer^ buffer)
{
unsigned char* bytes = nullptr;
CHK(As<WSS::IBufferByteAccess>(buffer)->Buffer(&bytes));
return bytes;
}
// Class to start and shutdown Media Foundation
class AutoMF
{
public:
AutoMF()
: _bInitialized(false)
{
CHK(MFStartup(MF_VERSION));
}
~AutoMF()
{
if (_bInitialized)
{
(void)MFShutdown();
}
}
private:
bool _bInitialized;
};
// Class to track error origin
template <size_t N>
HRESULT OriginateError(__in HRESULT hr, __in wchar_t const (&str)[N])
{
if (FAILED(hr))
{
::RoOriginateErrorW(hr, N - 1, str);
}
return hr;
}
// Class to track error origin
inline HRESULT OriginateError(__in HRESULT hr)
{
if (FAILED(hr))
{
::RoOriginateErrorW(hr, 0, nullptr);
}
return hr;
}
// Converts exceptions into HRESULTs
template <typename Lambda>
HRESULT ExceptionBoundary(Lambda&& lambda)
{
try
{
lambda();
return S_OK;
}
catch (Platform::Exception^ e)
{
return e->HResult;
}
catch (const std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
catch (const std::exception&)
{
return E_FAIL;
}
}
// Wraps an IMFSample in a C++/CX class to be able to define a callback delegate
ref class MediaSample sealed
{
internal:
MW::ComPtr<IMFSample> Sample;
};
delegate void MediaSampleHandler(MediaSample^ sample);
\ No newline at end of file
This diff is collapsed.
// Copyright (c) Microsoft. All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "MediaStreamSink.hpp"
#include "MFIncludes.hpp"
using namespace Media;
using namespace Microsoft::WRL;
using namespace Platform;
using namespace Windows::Foundation;
MediaStreamSink::MediaStreamSink(
__in const MW::ComPtr<IMFMediaSink>& sink,
__in DWORD id,
__in const MW::ComPtr<IMFMediaType>& mt,
__in MediaSampleHandler^ sampleHandler
)
: _shutdown(false)
, _id(-1)
, _width(0)
, _height(0)
{
CHK(MFCreateEventQueue(&_eventQueue));
CHK(MFCreateMediaType(&_curMT));
_UpdateMediaType(mt);
_sink = sink;
_id = id;
_sampleHandler = sampleHandler;
}
HRESULT MediaStreamSink::GetMediaSink(__deref_out IMFMediaSink **sink)
{
return ExceptionBoundary([this, sink]()
{
auto lock = _lock.LockExclusive();
CHKNULL(sink);
*sink = nullptr;
_VerifyNotShutdown();
CHK(_sink.CopyTo(sink));
});
}
HRESULT MediaStreamSink::GetIdentifier(__out DWORD *identifier)
{
return ExceptionBoundary([this, identifier]()
{
auto lock = _lock.LockExclusive();
CHKNULL(identifier);
_VerifyNotShutdown();
*identifier = _id;
});
}
HRESULT MediaStreamSink::GetMediaTypeHandler(__deref_out IMFMediaTypeHandler **handler)
{
return ExceptionBoundary([this, handler]()
{
auto lock = _lock.LockExclusive();
CHKNULL(handler);
*handler = nullptr;
_VerifyNotShutdown();
*handler = this;
this->AddRef();
});
}
void MediaStreamSink::RequestSample()
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
CHK(_eventQueue->QueueEventParamVar(MEStreamSinkRequestSample, GUID_NULL, S_OK, nullptr));
}
HRESULT MediaStreamSink::ProcessSample(__in_opt IMFSample *sample)
{
return ExceptionBoundary([this, sample]()
{
MediaSampleHandler^ sampleHandler;
auto mediaSample = ref new MediaSample();
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
if (sample == nullptr)
{
return;
}
mediaSample->Sample = sample;
sampleHandler = _sampleHandler;
}
// Call back without the lock taken to avoid deadlocks
sampleHandler(mediaSample);
});
}
HRESULT MediaStreamSink::PlaceMarker(__in MFSTREAMSINK_MARKER_TYPE /*markerType*/, __in const PROPVARIANT * /*markerValue*/, __in const PROPVARIANT * contextValue)
{
return ExceptionBoundary([this, contextValue]()
{
auto lock = _lock.LockExclusive();
CHKNULL(contextValue);
_VerifyNotShutdown();
CHK(_eventQueue->QueueEventParamVar(MEStreamSinkMarker, GUID_NULL, S_OK, contextValue));
});
}
HRESULT MediaStreamSink::Flush()
{
return ExceptionBoundary([this]()
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
});
}
HRESULT MediaStreamSink::GetEvent(__in DWORD flags, __deref_out IMFMediaEvent **event)
{
return ExceptionBoundary([this, flags, event]()
{
CHKNULL(event);
*event = nullptr;
ComPtr<IMFMediaEventQueue> eventQueue;
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
eventQueue = _eventQueue;
}
// May block for a while
CHK(eventQueue->GetEvent(flags, event));
});
}
HRESULT MediaStreamSink::BeginGetEvent(__in IMFAsyncCallback *callback, __in_opt IUnknown *state)
{
return ExceptionBoundary([this, callback, state]()
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
CHK(_eventQueue->BeginGetEvent(callback, state));
});
}
HRESULT MediaStreamSink::EndGetEvent(__in IMFAsyncResult *result, __deref_out IMFMediaEvent **event)
{
return ExceptionBoundary([this, result, event]()
{
auto lock = _lock.LockExclusive();
CHKNULL(event);
*event = nullptr;
_VerifyNotShutdown();
CHK(_eventQueue->EndGetEvent(result, event));
});
}
HRESULT MediaStreamSink::QueueEvent(
__in MediaEventType met,
__in REFGUID extendedType,
__in HRESULT status,
__in_opt const PROPVARIANT *value
)
{
return ExceptionBoundary([this, met, extendedType, status, value]()
{
auto lock = _lock.LockExclusive();
_VerifyNotShutdown();
CHK(_eventQueue->QueueEventParamVar(met, extendedType, status, value));
});
}
HRESULT MediaStreamSink::IsMediaTypeSupported(__in IMFMediaType *mediaType, __deref_out_opt IMFMediaType **closestMediaType)
{
bool supported = false;
HRESULT hr = ExceptionBoundary([this, mediaType, closestMediaType, &supported]()
{
auto lock = _lock.LockExclusive();
HRESULT hr = S_OK;
if (closestMediaType != nullptr)
{
*closestMediaType = nullptr;
}
CHKNULL(mediaType);
_VerifyNotShutdown();
supported = _IsMediaTypeSupported(mediaType);
});
// Avoid throwing an exception to return MF_E_INVALIDMEDIATYPE as this is not a exceptional case
return FAILED(hr) ? hr : supported ? S_OK : MF_E_INVALIDMEDIATYPE;
}
HRESULT MediaStreamSink::GetMediaTypeCount(__out DWORD *typeCount)
{
return ExceptionBoundary([this, typeCount]()
{
auto lock = _lock.LockExclusive();
CHKNULL(typeCount);
_VerifyNotShutdown();
// No media type provided by default (app needs to specify it)
*typeCount = 0;
});
}
HRESULT MediaStreamSink::GetMediaTypeByIndex(__in DWORD /*index*/, __deref_out IMFMediaType **mediaType)
{
HRESULT hr = ExceptionBoundary([this, mediaType]()
{
auto lock = _lock.LockExclusive();
CHKNULL(mediaType);
*mediaType = nullptr;
_VerifyNotShutdown();
});
// Avoid throwing an exception to return MF_E_NO_MORE_TYPES as this is not a exceptional case
return FAILED(hr) ? hr : MF_E_NO_MORE_TYPES;
}
HRESULT MediaStreamSink::SetCurrentMediaType(__in IMFMediaType *mediaType)
{
return ExceptionBoundary([this, mediaType]()
{
auto lock = _lock.LockExclusive();
HRESULT hr = S_OK;
CHKNULL(mediaType);
_VerifyNotShutdown();
if (!_IsMediaTypeSupported(mediaType))
{
CHK(MF_E_INVALIDMEDIATYPE);
}
_UpdateMediaType(mediaType);
});
}
HRESULT MediaStreamSink::GetCurrentMediaType(__deref_out_opt IMFMediaType **mediaType)
{
return ExceptionBoundary([this, mediaType]()
{
auto lock = _lock.LockExclusive();
CHKNULL(mediaType);
*mediaType = nullptr;
_VerifyNotShutdown();
ComPtr<IMFMediaType> mt;
CHK(MFCreateMediaType(&mt));
CHK(_curMT->CopyAllItems(mt.Get()));
*mediaType = mt.Detach();
});
}
HRESULT MediaStreamSink::GetMajorType(__out GUID *majorType)
{
return ExceptionBoundary([this, majorType]()
{
auto lock = _lock.LockExclusive();
CHKNULL(majorType);
_VerifyNotShutdown();
*majorType = _majorType;
});
}
void MediaStreamSink::InternalSetCurrentMediaType(__in const ComPtr<IMFMediaType>& mediaType)
{
auto lock = _lock.LockExclusive();
CHKNULL(mediaType);
_VerifyNotShutdown();
_UpdateMediaType(mediaType);
}
void MediaStreamSink::Shutdown()
{
auto lock = _lock.LockExclusive();
if (_shutdown)
{
return;
}
_shutdown = true;
(void)_eventQueue->Shutdown();
_eventQueue = nullptr;
_curMT = nullptr;
_sink = nullptr;
_sampleHandler = nullptr;
}
bool MediaStreamSink::_IsMediaTypeSupported(__in const ComPtr<IMFMediaType>& mt) const
{
GUID majorType;
GUID subType;
if (SUCCEEDED(mt->GetGUID(MF_MT_MAJOR_TYPE, &majorType)) &&
SUCCEEDED(mt->GetGUID(MF_MT_SUBTYPE, &subType)) &&
(majorType == _majorType) &&
(subType == _subType))
{
return true;
}
return false;
}
void MediaStreamSink::_UpdateMediaType(__in const ComPtr<IMFMediaType>& mt)
{
CHK(mt->GetGUID(MF_MT_MAJOR_TYPE, &_majorType));
CHK(mt->GetGUID(MF_MT_SUBTYPE, &_subType));
if (_majorType == MFMediaType_Video)
{
CHK(MFGetAttributeSize(mt.Get(), MF_MT_FRAME_SIZE, &_width, &_height));
}
CHK(mt->CopyAllItems(_curMT.Get()));
}
\ No newline at end of file
// Copyright (c) Microsoft. All rights reserved.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include "MFIncludes.hpp"
namespace Media {
class MediaStreamSink WrlSealed :
public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
IMFStreamSink,
IMFMediaEventGenerator,
IMFMediaTypeHandler
>
{
public:
MediaStreamSink(
__in const MW::ComPtr<IMFMediaSink>& sink,
__in DWORD id,
__in const MW::ComPtr<IMFMediaType>& mt,
__in MediaSampleHandler^ sampleHandler
);
//
// IMFStreamSink
//
IFACEMETHODIMP GetMediaSink(__deref_out IMFMediaSink **sink);
IFACEMETHODIMP GetIdentifier(__out DWORD *identifier);
IFACEMETHODIMP GetMediaTypeHandler(__deref_out IMFMediaTypeHandler **handler);
IFACEMETHODIMP ProcessSample(__in_opt IMFSample *sample);
IFACEMETHODIMP PlaceMarker(__in MFSTREAMSINK_MARKER_TYPE markerType, __in const PROPVARIANT * markerValue, __in const PROPVARIANT * contextValue);
IFACEMETHODIMP Flush();
//
// IMFMediaEventGenerator
//
IFACEMETHODIMP GetEvent(__in DWORD flags, __deref_out IMFMediaEvent **event);
IFACEMETHODIMP BeginGetEvent(__in IMFAsyncCallback *callback, __in_opt IUnknown *state);
IFACEMETHODIMP EndGetEvent(__in IMFAsyncResult *result, __deref_out IMFMediaEvent **event);
IFACEMETHODIMP QueueEvent(__in MediaEventType met, __in REFGUID extendedType, __in HRESULT status, __in_opt const PROPVARIANT *value);
//
// IMFMediaTypeHandler
//
IFACEMETHODIMP IsMediaTypeSupported(__in IMFMediaType *mediaType, __deref_out_opt IMFMediaType **closestMediaType);
IFACEMETHODIMP GetMediaTypeCount(__out DWORD *typeCount);
IFACEMETHODIMP GetMediaTypeByIndex(__in DWORD index, __deref_out IMFMediaType **mediaType);
IFACEMETHODIMP SetCurrentMediaType(__in IMFMediaType *mediaType);
IFACEMETHODIMP GetCurrentMediaType(__deref_out_opt IMFMediaType **mediaType);
IFACEMETHODIMP GetMajorType(__out GUID *majorType);
//
// Misc
//
void InternalSetCurrentMediaType(__in const MW::ComPtr<IMFMediaType>& mediaType);
void RequestSample();
void Shutdown();
private:
bool _IsMediaTypeSupported(__in const MW::ComPtr<IMFMediaType>& mt) const;
void _UpdateMediaType(__in const MW::ComPtr<IMFMediaType>& mt);
void _VerifyNotShutdown()
{
if (_shutdown)
{
CHK(MF_E_SHUTDOWN);
}
}
MW::ComPtr<IMFMediaSink> _sink;
MW::ComPtr<IMFMediaEventQueue> _eventQueue;
MW::ComPtr<IMFMediaType> _curMT;
MediaSampleHandler^ _sampleHandler;
GUID _majorType;
GUID _subType;
unsigned int _width;
unsigned int _height;
DWORD _id;
bool _shutdown;
MWW::SRWLock _lock;
};
}
\ No newline at end of file
// videoio to XAML bridge for OpenCV
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "opencv2\videoio\cap_winrt.hpp"
#include "cap_winrt_capture.hpp"
#include "cap_winrt_bridge.hpp"
#include "cap_winrt_video.hpp"
using namespace Windows::Foundation;
using namespace Windows::Media::Capture;
using namespace Windows::Media::MediaProperties;
using namespace Windows::Devices::Enumeration;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Microsoft::WRL;
using namespace Platform;
using namespace ::Concurrency;
using namespace ::std;
/***************************** VideoioBridge class ******************************/
// non-blocking
void VideoioBridge::requestForUIthreadAsync(int action, int widthp, int heightp)
{
reporter.report(action);
}
VideoioBridge& VideoioBridge::getInstance()
{
static VideoioBridge instance;
return instance;
}
void VideoioBridge::swapInputBuffers()
{
// TODO: already locked, check validity
// lock_guard<mutex> lock(inputBufferMutex);
swap(backInputPtr, frontInputPtr);
//if (currentFrame != frameCounter)
//{
// currentFrame = frameCounter;
// swap(backInputPtr, frontInputPtr);
//}
}
void VideoioBridge::swapOutputBuffers()
{
lock_guard<mutex> lock(outputBufferMutex);
swap(frontOutputBuffer, backOutputBuffer);
}
void VideoioBridge::allocateOutputBuffers()
{
frontOutputBuffer = ref new WriteableBitmap(width, height);
backOutputBuffer = ref new WriteableBitmap(width, height);
}
void VideoioBridge::imshow()
{
VideoioBridge::getInstance().swapOutputBuffers();
VideoioBridge::getInstance().requestForUIthreadAsync(cv::UPDATE_IMAGE_ELEMENT);
}
// end
\ No newline at end of file
// videoio to XAML bridge for OpenCV
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once
// this header is included in the XAML App, so it cannot include any
// OpenCV headers, or a static assert will be raised
#include <ppl.h>
#include <ppltasks.h>
#include <concrt.h>
#include <agile.h>
#include <opencv2\core.hpp>
#include <mutex>
#include <memory>
#include <atomic>
#include <functional>
// Class VideoioBridge (singleton) is needed because the interface for
// VideoCapture_WinRT in cap_winrt_capture.hpp is fixed by OpenCV.
class VideoioBridge
{
public:
static VideoioBridge& getInstance();
// call after initialization
void setReporter(Concurrency::progress_reporter<int> pr) { reporter = pr; }
// to be called from cvMain via cap_winrt on bg thread - non-blocking (async)
void requestForUIthreadAsync( int action, int width=0, int height=0 );
// TODO: modify in window.cpp: void cv::imshow( const String& winname, InputArray _img )
void imshow(/*cv::InputArray matToShow*/); // shows Mat in the cvImage element
void swapInputBuffers();
void allocateOutputBuffers();
void swapOutputBuffers();
int deviceIndex, width, height;
std::atomic<bool> bIsFrameNew;
std::mutex inputBufferMutex; // input is double buffered
unsigned char * frontInputPtr; // OpenCV reads this
unsigned char * backInputPtr; // Video grabber writes this
std::atomic<unsigned long> frameCounter;
unsigned long currentFrame;
std::mutex outputBufferMutex; // output is double buffered
Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ frontOutputBuffer; // OpenCV write this
Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ backOutputBuffer; // XAML reads this
Windows::UI::Xaml::Controls::Image ^cvImage;
private:
VideoioBridge() {
deviceIndex = 0;
width = 640;
height = 480;
deviceReady = false;
bIsFrameNew = false;
currentFrame = 0;
frameCounter = 0;
};
// singleton
VideoioBridge(VideoioBridge const &);
void operator=(const VideoioBridge &);
std::atomic<bool> deviceReady;
Concurrency::progress_reporter<int> reporter;
};
\ No newline at end of file
// Capture support for WinRT
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "precomp.hpp"
#include "cap_winrt_capture.hpp"
#include "cap_winrt_bridge.hpp"
#include "cap_winrt_video.hpp"
#include <opencv2\videoio\cap_winrt.hpp>
using namespace Windows::Foundation;
using namespace Windows::Media::Capture;
using namespace Windows::Media::MediaProperties;
using namespace Windows::Devices::Enumeration;
using namespace Platform;
using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Microsoft::WRL;
using namespace ::std;
// nb. VideoCapture_WinRT is not a singleton, so the Mats are made file statics
// we do not support more than one capture device simultaneously with the
// design at this time
// nb. inputBufferMutex was not able to guarantee that OpenCV Mats were
// ready to accept data in the UI thread (memory access exceptions were thrown
// even though buffer address was good).
// Therefore allocation of Mats is also done on the UI thread before the video
// device is initialized.
static cv::Mat frontInputMat;
static cv::Mat backInputMat;
namespace cv {
/***************************** exported control functions ******************************/
template <typename ...Args>
void winrt_startMessageLoop(std::function<void(Args...)>&& callback, Args... args)
{
auto asyncTask = ::concurrency::create_async([=](::concurrency::progress_reporter<int> reporter)
{
VideoioBridge::getInstance().setReporter(reporter);
// frame reading loop
callback(args...);
});
asyncTask->Progress = ref new AsyncActionProgressHandler<int>([=](IAsyncActionWithProgress<int>^ act, int progress)
{
int action = progress;
// these actions will be processed on the UI thread asynchronously
switch (action)
{
case OPEN_CAMERA:
winrt_openCamera();
break;
case CLOSE_CAMERA:
winrt_closeGrabber();
break;
case UPDATE_IMAGE_ELEMENT:
winrt_updateFrameContainer();
break;
}
});
}
template <typename ...Args>
void winrt_startMessageLoop(void callback(Args...), Args... args)
{
winrt_startMessageLoop(std::function<void(Args...)>(callback), args...);
}
void winrt_onVisibilityChanged(bool visible) {
if (visible)
{
VideoioBridge& bridge = VideoioBridge::getInstance();
// only start the grabber if the camera was opened in OpenCV
if (bridge.backInputPtr != nullptr)
{
if (Video::getInstance().isStarted()) return;
int device = bridge.deviceIndex;
int width = bridge.width;
int height = bridge.height;
winrt_initGrabber(device, width, height);
}
} else
{
//grabberStarted = false;
winrt_closeGrabber();
}
}
void winrt_imshow() {
VideoioBridge::getInstance().imshow();
}
void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image) {
VideoioBridge::getInstance().cvImage = image;
}
/********************************* Internal helpers ************************************/
void winrt_updateFrameContainer()
{
// copy output Mat to WBM
winrt_copyOutput();
// set XAML image element with image WBM
VideoioBridge::getInstance().cvImage->Source = VideoioBridge::getInstance().backOutputBuffer;
}
// performed on UI thread
bool winrt_openCamera()
{
VideoioBridge& bridge = VideoioBridge::getInstance();
int device = bridge.deviceIndex;
int width = bridge.width;
int height = bridge.height;
// buffers must alloc'd on UI thread
winrt_allocateBuffers(width, height);
// nb. video capture device init must be done on UI thread;
if (!Video::getInstance().isStarted())
{
winrt_initGrabber(device, width, height);
return true;
}
return false;
}
// performed on UI thread
void winrt_allocateBuffers(int width, int height)
{
VideoioBridge& bridge = VideoioBridge::getInstance();
// allocate input Mats (bgra8 = CV_8UC4, RGB24 = CV_8UC3)
frontInputMat.create(height, width, CV_8UC3);
backInputMat.create(height, width, CV_8UC3);
bridge.frontInputPtr = frontInputMat.ptr(0);
bridge.backInputPtr = backInputMat.ptr(0);
bridge.allocateOutputBuffers();
}
// non-blocking
bool winrt_initGrabber(int device, int w, int h) {
// nb. Video class is not exported outside of this DLL
// due to complexities in the CaptureFrameGrabber ref class
// as written in the header not mixing well with pure C++ classes
return Video::getInstance().initGrabber(device, w, h);
}
void winrt_closeGrabber() {
Video::getInstance().closeGrabber();
}
// nb on UI thread
void winrt_copyOutput() {
Video::getInstance().CopyOutput();
}
/********************************* VideoCapture_WinRT class ****************************/
VideoCapture_WinRT::VideoCapture_WinRT(int device) : started(false)
{
VideoioBridge::getInstance().deviceIndex = device;
}
bool VideoCapture_WinRT::isOpened() const
{
return true; // started;
}
// grab a frame:
// this will NOT block per spec
// should be called on the image processing thread, not the UI thread
bool VideoCapture_WinRT::grabFrame()
{
// if device is not started we must return true so retrieveFrame() is called to start device
// nb. we cannot start the device here because we do not know the size of the input Mat
if (!started) return true;
if (VideoioBridge::getInstance().bIsFrameNew)
{
return true;
}
// nb. if blocking is to be added:
// unique_lock<mutex> lock(VideoioBridge::getInstance().frameReadyMutex);
// VideoioBridge::getInstance().frameReadyEvent.wait(lock);
return false;
}
// should be called on the image processing thread after grabFrame
// see VideoCapture::read
bool VideoCapture_WinRT::retrieveFrame(int channel, cv::OutputArray outArray)
{
if (!started) {
int width, height;
width = outArray.size().width;
height = outArray.size().height;
if (width == 0) width = 640;
if (height == 0) height = 480;
VideoioBridge::getInstance().width = width;
VideoioBridge::getInstance().height = height;
// nb. Mats will be alloc'd on UI thread
// request device init on UI thread - this does not block, and is async
VideoioBridge::getInstance().requestForUIthreadAsync(OPEN_CAMERA,
outArray.size().width, outArray.size().height);
started = true;
return false;
}
if (!started) return false;
return VideoioBridge::getInstance().bIsFrameNew;
}
bool VideoCapture_WinRT::setProperty(int property_id, double value)
{
switch (property_id)
{
case CAP_PROP_FRAME_WIDTH:
size.width = (int)value;
break;
case CAP_PROP_FRAME_HEIGHT:
size.height = (int)value;
break;
default:
return false;
}
return true;
}
}
// end
\ No newline at end of file
// Capture support for WinRT
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "precomp.hpp"
#include <mutex>
#include <memory>
#include <condition_variable>
#include <atomic>
#include <agile.h>
// nb. implemented the newer IVideoCapture C++ interface so that we can work
// directly with Mat, not the older C cv interface
// (which may have added overhead for IPL file conversion)
namespace cv {
/******************* Internal helpers **************************************/
void winrt_updateFrameContainer();
bool winrt_openCamera();
bool winrt_initGrabber(int device, int w, int h);
void winrt_closeGrabber();
void winrt_copyOutput();
void winrt_allocateBuffers(int width, int height);
/******************* VideoCapture_WinRT class ******************************/
class VideoCapture_WinRT : public IVideoCapture
{
public:
VideoCapture_WinRT() : started(false) {}
VideoCapture_WinRT(int device);
virtual ~VideoCapture_WinRT() {}
// from base class IVideoCapture
virtual double getProperty(int) { return 0; }
virtual bool setProperty(int, double);
virtual bool grabFrame();
virtual bool retrieveFrame(int channel, cv::OutputArray outArray);
// Return the type of the capture object
virtual int getCaptureDomain() { return CAP_WINRT; }
virtual bool isOpened() const;
protected:
bool started;
CvSize size;
int bytesPerPixel;
unsigned long frameCurrent;
std::atomic<bool> isFrameNew;
};
}
\ No newline at end of file
This diff is collapsed.
// Video support with XAML
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "cap_winrt/CaptureFrameGrabber.hpp"
#include <mutex>
#include <memory>
class Video {
public:
bool initGrabber(int device, int w, int h);
void closeGrabber();
bool isStarted();
// singleton
static Video &getInstance();
void CopyOutput();
private:
// singleton
Video();
void _GrabFrameAsync(::Media::CaptureFrameGrabber^ frameGrabber);
bool listDevices();
Platform::Agile<Windows::Media::Capture::MediaCapture> m_capture;
Platform::Agile<Windows::Devices::Enumeration::DeviceInformationCollection> m_devices;
::Media::CaptureFrameGrabber^ m_frameGrabber;
bool listDevicesTask();
bool bChooseDevice;
bool bVerbose;
bool bFlipImageX;
//std::atomic<bool> bGrabberInited;
int m_deviceID;
int attemptFramerate;
std::atomic<bool> bIsFrameNew;
std::atomic<bool> bGrabberInited;
std::atomic<bool> bGrabberInitInProgress;
unsigned int width, height;
int bytesPerPixel;
};
\ No newline at end of file
This diff is collapsed.
...@@ -4,5 +4,9 @@ if(HAVE_CUDA) ...@@ -4,5 +4,9 @@ if(HAVE_CUDA)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter)
endif() endif()
if(WINRT_8_1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW")
endif()
ocv_define_module(videostab opencv_imgproc opencv_features2d opencv_video opencv_photo opencv_calib3d ocv_define_module(videostab opencv_imgproc opencv_features2d opencv_video opencv_photo opencv_calib3d
OPTIONAL opencv_cudawarping opencv_cudaoptflow opencv_videoio WRAP python) OPTIONAL opencv_cudawarping opencv_cudaoptflow opencv_videoio WRAP python)

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "video_capture_xaml", "video_capture_xaml", "{D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.Shared", "video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems", "{6A274B7F-3982-499E-B55A-1F12EF2E3EC0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.Windows", "video_capture_xaml\video_capture_xaml.Windows\video_capture_xaml.Windows.vcxproj", "{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.WindowsPhone", "video_capture_xaml\video_capture_xaml.WindowsPhone\video_capture_xaml.WindowsPhone.vcxproj", "{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{d7a82e7f-1535-4eec-aba9-2c8447669d33}*SharedItemsImports = 4
video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{6a274b7f-3982-499e-b55a-1f12ef2e3ec0}*SharedItemsImports = 9
video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{32fdab94-f87e-4f0a-89a4-9ec10a3b1d3d}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.ActiveCfg = Debug|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.Build.0 = Debug|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.Deploy.0 = Debug|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.ActiveCfg = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.Build.0 = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.Deploy.0 = Debug|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.ActiveCfg = Debug|x64
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.Build.0 = Debug|x64
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.Deploy.0 = Debug|x64
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.ActiveCfg = Release|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.Build.0 = Release|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.Deploy.0 = Release|ARM
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.Build.0 = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.Deploy.0 = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.ActiveCfg = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.Build.0 = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.Deploy.0 = Release|Win32
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.ActiveCfg = Release|x64
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.Build.0 = Release|x64
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.Deploy.0 = Release|x64
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.ActiveCfg = Debug|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.Build.0 = Debug|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.Deploy.0 = Debug|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.ActiveCfg = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.Build.0 = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.Deploy.0 = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|x64.ActiveCfg = Debug|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.ActiveCfg = Release|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.Build.0 = Release|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.Deploy.0 = Release|ARM
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.Build.0 = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.Deploy.0 = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.ActiveCfg = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.Build.0 = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.Deploy.0 = Release|Win32
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6A274B7F-3982-499E-B55A-1F12EF2E3EC0} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC}
{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC}
{D7A82E7F-1535-4EEC-ABA9-2C8447669D33} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<Runtime Condition="'$(ApplicationType)'=='Windows Phone'">WP</Runtime>
<Runtime Condition="'$(ApplicationType)'=='Windows Store'">WS</Runtime>
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\include\</OpenCV_Include>
<!--debug suffix for OpenCV dlls and libs -->
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
<DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
</PropertyGroup>
<ItemGroup>
<!-- Add required OpenCV dlls here-->
<!-- General-->
<None Include="$(OpenCV_Bin)opencv_core300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgproc300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_flann300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_features2d300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_imgcodecs300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<!-- Video processing -->
<None Include="$(OpenCV_Bin)opencv_videoio300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<!-- Face detection-->
<None Include="$(OpenCV_Bin)opencv_objdetect300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(OpenCV_Bin)opencv_ml300$(DebugSuffix).dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenCV_Include);%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<!--Add required OpenCV libs here-->
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_videoio300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_objdetect300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>
\ No newline at end of file
<Application x:Class="video_capture_xaml.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:video_capture_xaml" />
\ No newline at end of file
//
// App.xaml.cpp
// Implementation of the App class.
//
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "pch.h"
#include "MainPage.xaml.h"
#include "App.xaml.h"
using namespace video_capture_xaml;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml::Media::Animation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
Resuming += ref new Windows::Foundation::EventHandler<Platform::Object ^>(this, &video_capture_xaml::App::OnResuming);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs^ e)
{
#if _DEBUG
if (IsDebuggerPresent())
{
DebugSettings->EnableFrameRateCounter = true;
}
#endif
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active.
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = ref new Frame();
// TODO: Change this value to a cache size that is appropriate for your application.
rootFrame->CacheSize = 1;
if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
{
// TODO: Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete.
}
// Place the frame in the current Window
Window::Current->Content = rootFrame;
}
if (rootFrame->Content == nullptr)
{
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
// Removes the turnstile navigation for startup.
if (rootFrame->ContentTransitions != nullptr)
{
_transitions = ref new TransitionCollection();
for (auto transition : rootFrame->ContentTransitions)
{
_transitions->Append(transition);
}
}
rootFrame->ContentTransitions = nullptr;
_firstNavigatedToken = rootFrame->Navigated += ref new NavigatedEventHandler(this, &App::RootFrame_FirstNavigated);
#endif
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter.
if (!rootFrame->Navigate(MainPage::typeid, e->Arguments))
{
throw ref new FailureException("Failed to create initial page");
}
}
// Ensure the current window is active
Window::Current->Activate();
}
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
/// <summary>
/// Restores the content transitions after the app has launched.
/// </summary>
void App::RootFrame_FirstNavigated(Object^ sender, NavigationEventArgs^ e)
{
auto rootFrame = safe_cast<Frame^>(sender);
TransitionCollection^ newTransitions;
if (_transitions == nullptr)
{
newTransitions = ref new TransitionCollection();
newTransitions->Append(ref new NavigationThemeTransition());
}
else
{
newTransitions = _transitions;
}
rootFrame->ContentTransitions = newTransitions;
rootFrame->Navigated -= _firstNavigatedToken;
}
#endif
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
// TODO: Save application state and stop any background activity
}
void video_capture_xaml::App::OnResuming(Platform::Object ^sender, Platform::Object ^args)
{
// throw ref new Platform::NotImplementedException();
}
\ No newline at end of file
//
// App.xaml.h
// Declaration of the App class.
//
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "App.g.h"
namespace video_capture_xaml
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
ref class App sealed
{
public:
App();
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
private:
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
Windows::UI::Xaml::Media::Animation::TransitionCollection^ _transitions;
Windows::Foundation::EventRegistrationToken _firstNavigatedToken;
void RootFrame_FirstNavigated(Platform::Object^ sender, Windows::UI::Xaml::Navigation::NavigationEventArgs^ e);
#endif
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void OnResuming(Platform::Object ^sender, Platform::Object ^args);
};
}
// main.cpp
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "pch.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/videoio/cap_winrt.hpp>
using namespace cv;
namespace video_capture_xaml {
void cvMain()
{
VideoCapture cam;
// open the default camera
cam.open(0);
Mat edges;
Mat frame;
// process frames
while (1)
{
// get a new frame from camera - this is non-blocking per spec
cam >> frame;
// don't reprocess the same frame again
// nb if commented then flashing may occur
if (!cam.grab()) continue;
// image processing calculations here
// nb Mat frame is in RGB24 format (8UC3)
// select processing type 1 or 2
#if 0
// image manipulation example #1
// write color bar at row 100 for 200 rows
auto ar = frame.ptr(100);
int bytesPerPixel = 3;
int adjust = (int)(((float)30 / 100.0f) * 255.0);
for (int i = 0; i < 640 * 100 * bytesPerPixel;)
{
ar[i++] = adjust; // R
i++; // G
ar[i++] = 255 - adjust; // B
}
#else
// image processing example #2
// apply 'canny' filter
cvtColor(frame, edges, COLOR_RGB2GRAY);
GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
cvtColor(edges, frame, COLOR_GRAY2RGB);
#endif
// important step to get XAML image component updated
winrt_imshow();
}
}
}
\ No newline at end of file
//
// pch.cpp
// Include the standard header and generate the precompiled header.
//
#include "pch.h"
//
// pch.h
// Header for standard system include files.
//
#pragma once
#include <collection.h>
#include <ppltasks.h>
#include "App.xaml.h"
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>98633655-f156-43bb-b452-37cd6a71e3f0</SharedGUID>
<ItemsProjectGuid>{6a274b7f-3982-499e-b55a-1f12ef2e3ec0}</ItemsProjectGuid>
<ItemsRootNamespace>highgui_xaml</ItemsRootNamespace>
<ItemsProjectName>video_capture_xaml.Shared</ItemsProjectName>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml">
<SubType>Designer</SubType>
</ApplicationDefinition>
<ClCompile Include="$(MSBuildThisFileDirectory)App.xaml.cpp">
<DependentUpon>$(MSBuildThisFileDirectory)App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)main.cpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)App.xaml.h">
<DependentUpon>$(MSBuildThisFileDirectory)App.xaml</DependentUpon>
</ClInclude>
<ClCompile Include="$(MSBuildThisFileDirectory)pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h" />
</ItemGroup>
<ItemGroup>
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<CLCompile Include="$(MSBuildThisFileDirectory)App.xaml.cpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)App.xaml.h" />
<CLCompile Include="$(MSBuildThisFileDirectory)pch.cpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h" />
<ClCompile Include="$(MSBuildThisFileDirectory)main.cpp" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml" />
</ItemGroup>
</Project>
\ No newline at end of file
<Page x:Class="video_capture_xaml.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:video_capture_xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Margin="20,35,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="24"
TextWrapping="Wrap">
<Run Text="OpenCV: videoio implementation using XAML and Universal App Framework" />
<Run />
</TextBlock>
<Image Name="cvImage"
Width="640"
Height="480"
Margin="20,100,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
</Page>
\ No newline at end of file
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/videoio/cap_winrt.hpp>
using namespace video_capture_xaml;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
using namespace ::Windows::Foundation;
using namespace Windows::UI::Xaml::Media::Imaging;
namespace video_capture_xaml
{
// nb. implemented in main.cpp
void cvMain();
MainPage::MainPage()
{
InitializeComponent();
Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &video_capture_xaml::MainPage::OnVisibilityChanged);
// attach XAML elements
cv::winrt_setFrameContainer(cvImage);
// start (1) frame-grabbing loop and (2) message loop
//
// 1. Function passed as an argument must implement common OCV reading frames
// pattern (see cv::VideoCapture documentation) AND call cv::winrt_imgshow().
// 2. Message processing loop required to overcome WinRT container and type
// conversion restrictions. OCV provides default implementation
cv::winrt_startMessageLoop(cvMain);
}
}
void video_capture_xaml::MainPage::OnVisibilityChanged(Platform::Object ^sender,
Windows::UI::Core::VisibilityChangedEventArgs ^e)
{
cv::winrt_onVisibilityChanged(e->Visible);
}
//
// MainPage.xaml.h
// Declaration of the MainPage class.
//
#pragma once
#include "MainPage.g.h"
namespace video_capture_xaml
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
private:
void OnVisibilityChanged(Platform::Object ^sender, Windows::UI::Core::VisibilityChangedEventArgs ^e);
};
}
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
<Identity Name="dd4947e8-f250-49d1-be17-4442dfea2737" Publisher="CN=daver_000" Version="1.0.0.0" />
<Properties>
<DisplayName>video_capture_xaml.Windows</DisplayName>
<PublisherDisplayName>daver_000</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.0</OSMinVersion>
<OSMaxVersionTested>6.3.0</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="video_capture_xaml_Windows.App">
<m2:VisualElements DisplayName="video_capture_xaml.Windows" Square150x150Logo="Assets\Logo.png" Square30x30Logo="Assets\SmallLogo.png" Description="video_capture_xaml.Windows" ForegroundText="light" BackgroundColor="#464646">
<m2:SplashScreen Image="Assets\SplashScreen.png" />
</m2:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="webcam" />
</Capabilities>
</Package>
\ No newline at end of file
notes for OpenCV WinRT implementation:
cvMain() in main.cpp
implements the image processing and OpenCV app control
it is running on a background thread, started by XAML
see file main.cpp
in the Application project
class VideoCapture_WinRT:
implements the IVideoCapture interface from OpenCV
video is initialized and frames are grabbed on the UI thread
see files cap_winrt.hpp/cpp
class HighguiBridge, a singleton
implements the OpenCV Highgui functions for XAML (limited at this time),
and also bridges to the UI thread functions for XAML and video operations.
see files cap_winrt_highgui.hpp/cpp
class Video, a singleton
encapsulates the Media Foundation interface needed for video initialization and grabbing.
called through Highgui and XAML, only on the UI thread
see files cap_winrt_video.hpp/cpp
threading:
requests from the OpenCV bg thread to the Video/XAML UI thread
are made through HighguiBridge::requestForUIthreadAsync(), which uses
the "progress reporter" method provided by the WinRT class
IAsyncActionWithProgress. Also the bg thread is started by create_async().
see file MainPage.xaml.cpp
in the Application project
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{32fdab94-f87e-4f0a-89a4-9ec10a3b1d3d}</ProjectGuid>
<RootNamespace>video_capture_xaml</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.1</ApplicationTypeRevision>
<ProjectName>video_capture_xaml.Windows</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems" Label="Shared" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<PackageCertificateKeyFile>video_capture_xaml.Windows_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LibraryPath>$(OPENCV_WINRT_INSTALL_DIR)WS\8.1\x86\x86\vc12\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<IgnoreImportLibrary>false</IgnoreImportLibrary>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ProjectReference>
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
</ProjectReference>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ProjectReference>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
<Link>
<AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="MainPage.xaml.h">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Page Include="MainPage.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="video_capture_xaml.Windows_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\Logo.scale-100.png" />
<Image Include="Assets\SmallLogo.scale-100.png" />
<Image Include="Assets\StoreLogo.scale-100.png" />
<Image Include="Assets\SplashScreen.scale-100.png" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="MainPage.xaml.cpp">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<Xml Include="Assets\haarcascade_frontalface_alt.xml" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Assets">
<UniqueIdentifier>{ef9b8c45-f2b7-4eec-a8b4-a9b340be770b}</UniqueIdentifier>
<Extensions>bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Page Include="MainPage.xaml" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="MainPage.xaml.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MainPage.xaml.h" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
</ItemGroup>
<ItemGroup>
<None Include="video_capture_xaml.Windows_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\Logo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SmallLogo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\StoreLogo.scale-100.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SplashScreen.scale-100.png">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<Xml Include="Assets\haarcascade_frontalface_alt.xml">
<Filter>Assets</Filter>
</Xml>
</ItemGroup>
</Project>
\ No newline at end of file
<Page x:Class="video_capture_xaml.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:video_capture_xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Margin="20,35,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="24"
TextWrapping="Wrap">
<Run Text="OpenCV: videoio" />
<Run />
</TextBlock>
<Image Name="cvImage"
Width="640"
Height="480"
Margin="20,100,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
</Page>
\ No newline at end of file
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/videoio/cap_winrt.hpp>
using namespace video_capture_xaml;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
using namespace ::Windows::Foundation;
using namespace Windows::UI::Xaml::Media::Imaging;
namespace video_capture_xaml {
// nb. implemented in main.cpp
void cvMain();
MainPage::MainPage()
{
InitializeComponent();
Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &video_capture_xaml::MainPage::OnVisibilityChanged);
// attach XAML elements
cv::winrt_setFrameContainer(cvImage);
// start (1) frame-grabbing loop and (2) message loop
//
// 1. Function passed as an argument must implement common OCV reading frames
// pattern (see cv::VideoCapture documentation) AND call cv::winrt_imgshow().
// 2. Message processing loop required to overcome WinRT container and type
// conversion restrictions. OCV provides default implementation
cv::winrt_startMessageLoop(cvMain);
}
void video_capture_xaml::MainPage::OnVisibilityChanged(Platform::Object ^sender,
Windows::UI::Core::VisibilityChangedEventArgs ^e)
{
cv::winrt_onVisibilityChanged(e->Visible);
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
(void)e; // Unused parameter
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows::Phone::UI::Input::HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
}
\ No newline at end of file
//
// MainPage.xaml.h
// Declaration of the MainPage class.
//
#pragma once
#include "MainPage.g.h"
namespace video_capture_xaml
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
void OnVisibilityChanged(Platform::Object ^sender, Windows::UI::Core::VisibilityChangedEventArgs ^e);
};
}
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
<Identity Name="dfafcbf2-a525-4ed0-9b6c-4e8bd5a9c0ba"
Publisher="CN=daver_000"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="dfafcbf2-a525-4ed0-9b6c-4e8bd5a9c0ba" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>video_capture_xaml.WindowsPhone</DisplayName>
<PublisherDisplayName>daver_000</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.1</OSMinVersion>
<OSMaxVersionTested>6.3.1</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="video_capture_xaml_WindowsPhone.App">
<m3:VisualElements
DisplayName="video_capture_xaml.WindowsPhone"
Square150x150Logo="Assets\Logo.png"
Square44x44Logo="Assets\SmallLogo.png"
Description="video_capture_xaml.WindowsPhone"
ForegroundText="light"
BackgroundColor="transparent">
<m3:DefaultTile Wide310x150Logo="Assets\WideLogo.png" Square71x71Logo="Assets\Square71x71Logo.png"/>
<m3:SplashScreen Image="Assets\SplashScreen.png"/>
<m3:ApplicationView MinWidth="width320"/> <!--Used in XAML Designer. DO NOT REMOVE-->
</m3:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClientServer" />
<DeviceCapability Name="webcam" />
</Capabilities>
</Package>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{d7a82e7f-1535-4eec-aba9-2c8447669d33}</ProjectGuid>
<RootNamespace>video_capture_xaml</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Phone</ApplicationType>
<ApplicationTypeRevision>8.1</ApplicationTypeRevision>
<ProjectName>video_capture_xaml.WindowsPhone</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_wp81</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_wp81</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120_wp81</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120_wp81</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems" Label="Shared" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(OPENCV_WINRT_INSTALL_DIR)WP\8.1\x86\x86\vc12\lib;$(VC_LibraryPath_x86);$(WindowsPhoneSDK_LibraryPath_x86);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LibraryPath>$(OPENCV_WINRT_INSTALL_DIR)WP\8.1\ARM\ARM\vc12\lib;$(VC_LibraryPath_ARM);$(WindowsPhoneSDK_LibraryPath_arm);</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../../../../../modules/core/include;../../../../../modules/flann/include;../../../../../modules/videoio/include;../../../../../modules/hal/include;../../../../../modules/imgproc/include;../../../../../modules/features2d/include;%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>opencv_core300d.lib;opencv_imgproc300d.lib;opencv_videoio300d.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../../../../../modules/core/include;../../../../../modules/flann/include;../../../../../modules/videoio/include;../../../../../modules/hal/include;../../../../../modules/imgproc/include;../../../../../modules/features2d/include;%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>opencv_core300d.lib;opencv_imgproc300d.lib;opencv_videoio300d.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="MainPage.xaml.h">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Page Include="MainPage.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Image Include="Assets\Logo.scale-240.png" />
<Image Include="Assets\SmallLogo.scale-240.png" />
<Image Include="Assets\Square71x71Logo.scale-240.png" />
<Image Include="Assets\StoreLogo.scale-240.png" />
<Image Include="Assets\SplashScreen.scale-240.png" />
<Image Include="Assets\WideLogo.scale-240.png" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="MainPage.xaml.cpp">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="video_capture_xaml.WindowsPhone_TemporaryKey.pfx" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Assets">
<UniqueIdentifier>{$guid3$}</UniqueIdentifier>
<Extensions>bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
</Filter>
<Image Include="Assets\Logo.scale-240.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SmallLogo.scale-240.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\Square71x71Logo.scale-240.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\StoreLogo.scale-240.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SplashScreen.scale-240.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\WideLogo.scale-240.png">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<ClCompile Include="MainPage.xaml.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MainPage.xaml.h" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest" />
</ItemGroup>
<ItemGroup>
<Page Include="MainPage.xaml" />
</ItemGroup>
<ItemGroup>
<None Include="video_capture_xaml.WindowsPhone_TemporaryKey.pfx" />
</ItemGroup>
</Project>
\ No newline at end of file
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