Home | History | Annotate | Download | only in src
      1 // videoio to XAML bridge for OpenCV
      2 
      3 // Copyright (c) Microsoft Open Technologies, Inc.
      4 // All rights reserved.
      5 //
      6 // (3 - clause BSD License)
      7 //
      8 // Redistribution and use in source and binary forms, with or without modification, are permitted provided that
      9 // the following conditions are met:
     10 //
     11 // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
     12 // following disclaimer.
     13 // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
     14 // following disclaimer in the documentation and/or other materials provided with the distribution.
     15 // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
     16 // promote products derived from this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
     19 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     20 // PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
     21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
     22 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
     24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25 // POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #pragma once
     28 
     29 // this header is included in the XAML App, so it cannot include any
     30 // OpenCV headers, or a static assert will be raised
     31 
     32 #include <ppl.h>
     33 #include <ppltasks.h>
     34 #include <concrt.h>
     35 #include <agile.h>
     36 #include <opencv2\core.hpp>
     37 
     38 #include <mutex>
     39 #include <memory>
     40 #include <atomic>
     41 #include <functional>
     42 
     43 
     44 // Class VideoioBridge (singleton) is needed because the interface for
     45 // VideoCapture_WinRT in cap_winrt_capture.hpp is fixed by OpenCV.
     46 class VideoioBridge
     47 {
     48 public:
     49 
     50     static VideoioBridge& getInstance();
     51 
     52     // call after initialization
     53     void    setReporter(Concurrency::progress_reporter<int> pr) { reporter = pr; }
     54 
     55     // to be called from cvMain via cap_winrt on bg thread - non-blocking (async)
     56     void    requestForUIthreadAsync(int action);
     57 
     58     // TODO: modify in window.cpp: void cv::imshow( const String& winname, InputArray _img )
     59     void    imshow(/*cv::InputArray matToShow*/);   // shows Mat in the cvImage element
     60     void    swapInputBuffers();
     61     void    allocateOutputBuffers();
     62     void    swapOutputBuffers();
     63     void    updateFrameContainer();
     64     bool    openCamera();
     65     void    allocateBuffers(int width, int height);
     66 
     67     int     getDeviceIndex();
     68     void    setDeviceIndex(int index);
     69     int     getWidth();
     70     void    setWidth(int width);
     71     int     getHeight();
     72     void    setHeight(int height);
     73 
     74     std::atomic<bool>           bIsFrameNew;
     75     std::mutex                  inputBufferMutex;   // input is double buffered
     76     unsigned char *             frontInputPtr;      // OpenCV reads this
     77     unsigned char *             backInputPtr;       // Video grabber writes this
     78     std::atomic<unsigned long>  frameCounter;
     79     unsigned long               currentFrame;
     80 
     81     std::mutex                  outputBufferMutex;  // output is double buffered
     82     Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ frontOutputBuffer;  // OpenCV write this
     83     Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ backOutputBuffer;   // XAML reads this
     84     Windows::UI::Xaml::Controls::Image ^cvImage;
     85 
     86 private:
     87 
     88     VideoioBridge() {
     89         deviceIndex = 0;
     90         width = 640;
     91         height = 480;
     92         deviceReady = false;
     93         bIsFrameNew = false;
     94         currentFrame = 0;
     95         frameCounter = 0;
     96     };
     97 
     98     // singleton
     99     VideoioBridge(VideoioBridge const &);
    100     void operator=(const VideoioBridge &);
    101 
    102     std::atomic<bool>   deviceReady;
    103     Concurrency::progress_reporter<int> reporter;
    104 
    105     // Mats are wrapped with singleton class, we do not support more than one
    106     // capture device simultaneously with the design at this time
    107     //
    108     // nb. inputBufferMutex was not able to guarantee that OpenCV Mats were
    109     // ready to accept data in the UI thread (memory access exceptions were thrown
    110     // even though buffer address was good).
    111     // Therefore allocation of Mats is also done on the UI thread before the video
    112     // device is initialized.
    113     cv::Mat frontInputMat;
    114     cv::Mat backInputMat;
    115 
    116     int deviceIndex, width, height;
    117 };