OSVR-Core
directx_camera_server.h
Go to the documentation of this file.
1 
12 // Copyright 2015 Sensics, Inc.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "License");
15 // you may not use this file except in compliance with the License.
16 // You may obtain a copy of the License at
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 // See the License for the specific language governing permissions and
24 // limitations under the License.
25 
26 #ifdef _WIN32
27 #ifndef INCLUDED_directx_camera_server_h_GUID_9322F126_0DA4_4DB9_11F3_DDBF76A6D9D9
28 #define INCLUDED_directx_camera_server_h_GUID_9322F126_0DA4_4DB9_11F3_DDBF76A6D9D9
29 
30 // Internal Includes
31 #include "MediaSampleExchange.h"
32 #include "SampleGrabberWrapper.h"
33 #include "base_camera_server.h"
34 #include "comutils/ComInit.h"
35 #include "comutils/ComPtr.h"
36 
37 // Library/third-party includes
38 #include <osvr/Util/TimeValue.h>
39 
40 // Standard includes
41 #include <functional>
42 #include <memory>
43 #include <stdexcept>
44 #include <vector>
45 
46 // Include files for DirectShow video input
47 #define NO_DSHOW_STRSAFE
48 #include <dshow.h>
49 
50 // All we need from the "deprecated" qedit.h header file are these few lousy
51 // names:
52 // - ISampleGrabber
53 // - ISampleGrabberCB
54 // - CLSID_SampleGrabber
55 // - IID_ISampleGrabber
56 // - CLSID_NullRenderer
57 // - IID_ISampleGrabberCB
58 //
59 // The NullRenderer CLSID is used in the NullRenderFilter.cpp file, the rest are
60 // used in the SampleGrabberWrapper.cpp and directx_samplegrabber_callback.*
61 // files.
62 
63 struct ConstructionError : std::runtime_error {
64  ConstructionError(const char objName[])
65  : std::runtime_error(
66  std::string("directx_camera_server: Can't create ") + objName) {}
67 };
68 
69 // This code (and the code in the derived videofile server) is
70 // based on information the book "Programming Microsoft DirectShow
71 // for Digital Video and Television", Mark D. Pesce. Microsoft Press.
72 // ISBN 0-7356-1821-6. This book was required reading for me to
73 // understand how the filter graphs run, how to control replay rate,
74 // and how to reliably grab all of the samples from a stream.
75 // The chapter on using the Sample Grabber Filter
76 // (ch. 11) was particularly relevant. Note that I did not break the seal
77 // on the enclosed disk, which would require me to agree to licensing terms
78 // that include me not providing anyone with copies of my modified versions
79 // of the sample code in source-code format. Instead, I used the information
80 // gained in the reading of the book to write by hand my own version of this
81 // code. What a sick world we live in when example code can't be freely
82 // shared.
83 
84 // If you're using Visual Studio, an old (pre-7.0) version of the Microsoft
85 // Platform SDK must be installed on your machine to make this work; the qedit.h
86 // header is used in very encapsulated locations, but used nonetheless.
87 // If you're building with MinGW64, they've got a reimplementation of that
88 // header that works fine, no worries.
89 
90 using FilterOperation = std::function<void(IBaseFilter &)>;
91 
92 class directx_camera_server : public base_camera_server {
93  public:
94  using BufferType = std::vector<unsigned char>;
95 
97  directx_camera_server(int which, unsigned width = 0, unsigned height = 0);
99  directx_camera_server(std::string const &pathPrefix, unsigned width = 0,
100  unsigned height = 0);
101 
104  directx_camera_server(std::string const &pathPrefix,
105  FilterOperation const &sourceConfig);
106 
107  virtual ~directx_camera_server(void);
108 
110  virtual unsigned get_num_colors() const { return 3; };
111 
113  virtual bool read_image_to_memory(unsigned minX = 255, unsigned maxX = 0,
114  unsigned minY = 255, unsigned maxY = 0,
115  double exposure_millisecs = 250.0);
116 
118  virtual bool get_pixel_from_memory(unsigned X, unsigned Y, vrpn_uint8 &val,
119  int RGB = 0) const;
120  virtual bool get_pixel_from_memory(unsigned X, unsigned Y, vrpn_uint16 &val,
121  int RGB = 0) const;
122 
124  BufferType const &get_pixel_buffer() const { return _buffer; }
125 
127  BufferType &get_pixel_buffer() { return _buffer; }
128 
130  osvr::util::time::TimeValue const &get_buffer_timestamp() const {
131  return ts_;
132  }
133 
136  bool isOpened(void) const { return _started_graph; }
137 
138  std::string const &getPath() const { return devicePath_; }
139 
140  protected:
141  bool start_com_and_graphbuilder();
142  bool open_moniker_and_finish_setup(comutils::Ptr<IMoniker> pMoniker,
143  FilterOperation const &sourceConfig,
144  unsigned width, unsigned height);
145  virtual void close_device(void);
146 
148  directx_camera_server();
149 
151 
152  // Objects needed for DirectShow video input.
154  _pGraph; // Constructs a DirectShow filter graph
155 
157  _pMediaControl; // Handles media streaming in the filter graph
158 
159  comutils::Ptr<ICaptureGraphBuilder2> _pBuilder; // Filter graph builder
160 
163  std::unique_ptr<SampleGrabberWrapper> _pSampleGrabberWrapper;
164 
165  // Memory pointers used to get non-virtual memory
166  BufferType _buffer; //< Buffer for what comes from camera
167  bool _started_graph = false; //< Did we start the filter graph running?
168  unsigned _mode = 0; //< Mode 0 = running, Mode 1 = paused.
169 
170  long _stride; //< How many bytes to skip when going to next line (may be
171  // negative for upside-down images)
172 
173  // How we interact with the sample grabber callback.
174  MediaSampleExchangePtr sampleExchange_;
175 
176  virtual bool open_and_find_parameters(const int which, unsigned width,
177  unsigned height);
178  bool open_and_find_parameters(std::string const &pathPrefix,
179  FilterOperation const &sourceConfig,
180  unsigned width = 0, unsigned height = 0);
181  virtual bool read_one_frame(unsigned minX, unsigned maxX, unsigned minY,
182  unsigned maxY, unsigned exposure_millisecs);
183 
184  private:
185  void allocate_buffer();
186  std::string devicePath_;
188 };
189 
190 #endif // INCLUDED_directx_camera_server_h_GUID_9322F126_0DA4_4DB9_11F3_DDBF76A6D9D9
191 #endif // _WIN32
Header with a template alias for the desired COM smart pointer.
Definition: TypeSafeIdHash.h:44
Header providing RAII-style handling of COM initialization.
Header providing a C++ wrapper around TimeValueC.h.
boost::intrusive_ptr< T > Ptr
Template alias for our desired COM smart pointer.
Definition: ComPtr.h:40
std::unique_ptr< ComInit > ComInstance
unique_ptr for holding the lifetime of a ComInit.
Definition: ComInit.h:42
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
Definition: base_camera_server.h:196