OSVR-Core
DirectShowHDKCameraFactory.h
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_DirectShowHDKCameraFactory_h_GUID_383B0AE1_8BD2_4B9D_5176_ABEFEF534DBE
26 #define INCLUDED_DirectShowHDKCameraFactory_h_GUID_383B0AE1_8BD2_4B9D_5176_ABEFEF534DBE
27 
28 // Internal Includes
29 #include "directx_camera_server.h"
30 
31 // Library/third-party includes
32 // - none
33 
34 // Standard includes
35 #include <memory>
36 #include <iostream>
37 
38 #include <ks.h>
39 #include <ksmedia.h>
40 #include <ksproxy.h>
41 
42 // On the HDK IR camera, this actually puts the camera into the correct
43 // high-gain mode and has apparently nothing to do with powerline frequency.
44 inline void setGainMode(IBaseFilter &filter, bool highGain) {
45  auto ksPropSet = comutils::Ptr<IKsPropertySet>{};
46  filter.QueryInterface(__uuidof(IKsPropertySet), AttachPtr(ksPropSet));
47  if (!ksPropSet) {
48  // std::cout << "Couldn't get ksPropSet" << std::endl;
49  return;
50  }
51  auto prop = KSPROPERTY{};
52  prop.Set = GUID{STATICGUIDOF(
53  PROPSETID_VIDCAP_VIDEOPROCAMP)}; // workaround undefined reference, no
54  // need to link for one silly guid.
55  prop.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY;
56 
57  auto supportType = DWORD{0};
58  auto hr = ksPropSet->QuerySupported(prop.Set, prop.Id, &supportType);
59  if (SUCCEEDED(hr) && (supportType & KSPROPERTY_SUPPORT_SET)) {
60  // If we got here, we know we can set the "powerline" property
61  // past this point MSDN was almost useless to a non-driver-writer
62  // Chrome source code path below was a useful reference
63  // chromium/src/media/capture/video/win/video_capture_device_win.cc
64  static const long POWERLINE_DISABLED = 0;
65  static const long POWERLINE_50HZ = 1;
66  static const long POWERLINE_60HZ = 2;
67 
68  auto propData = KSPROPERTY_VIDEOPROCAMP_S{};
69  propData.Property = prop;
70  propData.Property.Flags = KSPROPERTY_TYPE_SET;
71 
72  propData.Value = highGain ? POWERLINE_50HZ : POWERLINE_60HZ;
73  propData.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
74 
75  hr = ksPropSet->Set(prop.Set, prop.Id, &propData, sizeof(propData),
76  &propData, sizeof(propData));
77 
78  if (FAILED(hr)) {
79  std::cout
80  << "Tried but failed to put the camera in desired gain mode..."
81  << std::endl;
82  }
83  }
84 }
85 
86 inline std::unique_ptr<directx_camera_server> getDirectShowHDKCamera(bool highGain = true) {
87  // This string begins the DevicePath provided by Windows for the HDK's
88  // camera.
89  static const auto HDK_CAMERA_PATH_PREFIX =
90  "\\\\?\\usb#vid_0bda&pid_57e8&mi_00";
91  auto ret = std::unique_ptr<directx_camera_server>{new directx_camera_server(
92  HDK_CAMERA_PATH_PREFIX,
93  [highGain](IBaseFilter &filter) { setGainMode(filter, highGain); })};
94 
95  if (!ret->working()) {
96  // If it didn't start up right, just ditch it now.
97  ret.reset();
98  }
99  return ret;
100 }
101 
102 #endif // INCLUDED_DirectShowHDKCameraFactory_h_GUID_383B0AE1_8BD2_4B9D_5176_ABEFEF534DBE
boost::intrusive_ptr< T > Ptr
Template alias for our desired COM smart pointer.
Definition: ComPtr.h:40