Path: blob/master/modules/videoio/src/cap_winrt_capture.cpp
16354 views
// Capture support for WinRT12// Copyright (c) Microsoft Open Technologies, Inc.3// All rights reserved.4//5// (3 - clause BSD License)6//7// Redistribution and use in source and binary forms, with or without modification, are permitted provided that8// the following conditions are met:9//10// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the11// following disclaimer.12// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the13// following disclaimer in the documentation and/or other materials provided with the distribution.14// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or15// promote products derived from this software without specific prior written permission.16//17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED18// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A19// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY20// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING23// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE24// POSSIBILITY OF SUCH DAMAGE.252627#include "precomp.hpp"28#include "cap_winrt_capture.hpp"29#include "cap_winrt_bridge.hpp"30#include "cap_winrt_video.hpp"31#include <opencv2\videoio\cap_winrt.hpp>3233using namespace Windows::Foundation;34using namespace Windows::Media::Capture;35using namespace Windows::Media::MediaProperties;36using namespace Windows::Devices::Enumeration;3738using namespace Platform;3940using namespace Windows::UI::Xaml::Media::Imaging;41using namespace Microsoft::WRL;4243using namespace ::std;4445namespace cv {4647/******************************* exported API functions **************************************/4849template <typename ...Args>50void winrt_startMessageLoop(std::function<void(Args...)>&& callback, Args... args)51{52auto asyncTask = ::concurrency::create_async([=](::concurrency::progress_reporter<int> reporter)53{54VideoioBridge::getInstance().setReporter(reporter);5556// frame reading loop57callback(args...);58});5960asyncTask->Progress = ref new AsyncActionProgressHandler<int>([=](IAsyncActionWithProgress<int>^ act, int progress)61{62int action = progress;6364// these actions will be processed on the UI thread asynchronously65switch (action)66{67case OPEN_CAMERA:68VideoioBridge::getInstance().openCamera();69break;70case CLOSE_CAMERA:71Video::getInstance().closeGrabber();72break;73case UPDATE_IMAGE_ELEMENT:74VideoioBridge::getInstance().updateFrameContainer();75break;76}77});78}7980template <typename ...Args>81void winrt_startMessageLoop(void callback(Args...), Args... args)82{83winrt_startMessageLoop(std::function<void(Args...)>(callback), args...);84}8586void winrt_onVisibilityChanged(bool visible)87{88if (visible)89{90VideoioBridge& bridge = VideoioBridge::getInstance();9192// only start the grabber if the camera was opened in OpenCV93if (bridge.backInputPtr != nullptr)94{95if (Video::getInstance().isStarted()) return;9697int device = bridge.getDeviceIndex();98int width = bridge.getWidth();99int height = bridge.getHeight();100101Video::getInstance().initGrabber(device, width, height);102}103} else104{105//grabberStarted = false;106Video::getInstance().closeGrabber();107}108}109110void winrt_imshow()111{112VideoioBridge::getInstance().imshow();113}114115void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image)116{117VideoioBridge::getInstance().cvImage = image;118}119120/********************************* VideoCapture_WinRT class ****************************/121122VideoCapture_WinRT::VideoCapture_WinRT(int device) : started(false)123{124VideoioBridge::getInstance().setDeviceIndex(device);125}126127bool VideoCapture_WinRT::isOpened() const128{129return true; // started;130}131132// grab a frame:133// this will NOT block per spec134// should be called on the image processing thread, not the UI thread135bool VideoCapture_WinRT::grabFrame()136{137// if device is not started we must return true so retrieveFrame() is called to start device138// nb. we cannot start the device here because we do not know the size of the input Mat139if (!started) return true;140141if (VideoioBridge::getInstance().bIsFrameNew)142{143return true;144}145146// nb. if blocking is to be added:147// unique_lock<mutex> lock(VideoioBridge::getInstance().frameReadyMutex);148// VideoioBridge::getInstance().frameReadyEvent.wait(lock);149return false;150}151152// should be called on the image processing thread after grabFrame153// see VideoCapture::read154bool VideoCapture_WinRT::retrieveFrame(int channel, cv::OutputArray outArray)155{156if (!started) {157158int width, height;159width = outArray.size().width;160height = outArray.size().height;161if (width == 0) width = 640;162if (height == 0) height = 480;163164VideoioBridge::getInstance().setWidth(width);165VideoioBridge::getInstance().setHeight(height);166167// nb. Mats will be alloc'd on UI thread168169// request device init on UI thread - this does not block, and is async170VideoioBridge::getInstance().requestForUIthreadAsync(OPEN_CAMERA);171172started = true;173return false;174}175176if (!started) return false;177178return VideoioBridge::getInstance().bIsFrameNew;179}180181182bool VideoCapture_WinRT::setProperty(int property_id, double value)183{184switch (property_id)185{186case CAP_PROP_FRAME_WIDTH:187size.width = (int)value;188break;189case CAP_PROP_FRAME_HEIGHT:190size.height = (int)value;191break;192default:193return false;194}195return true;196}197}198199// end200201