WPILibC++  unspecified
SourceImpl.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef CSCORE_SOURCEIMPL_H_
9 #define CSCORE_SOURCEIMPL_H_
10 
11 #include <atomic>
12 #include <cstddef>
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include <wpi/ArrayRef.h>
18 #include <wpi/StringMap.h>
19 #include <wpi/StringRef.h>
20 #include <wpi/condition_variable.h>
21 #include <wpi/mutex.h>
22 
23 #include "Frame.h"
24 #include "Image.h"
25 #include "PropertyImpl.h"
26 #include "cscore_cpp.h"
27 
28 namespace cs {
29 
30 class SourceImpl {
31  friend class Frame;
32 
33  public:
34  explicit SourceImpl(wpi::StringRef name);
35  virtual ~SourceImpl();
36  SourceImpl(const SourceImpl& oth) = delete;
37  SourceImpl& operator=(const SourceImpl& oth) = delete;
38 
39  wpi::StringRef GetName() const { return m_name; }
40 
41  void SetDescription(wpi::StringRef description);
42  wpi::StringRef GetDescription(wpi::SmallVectorImpl<char>& buf) const;
43 
44  void SetConnected(bool connected);
45  bool IsConnected() const { return m_connected; }
46 
47  // Functions to keep track of the overall number of sinks connected to this
48  // source. Primarily used by sinks to determine if other sinks are using
49  // the same source.
50  int GetNumSinks() const { return m_numSinks; }
51  void AddSink() {
52  ++m_numSinks;
53  NumSinksChanged();
54  }
55  void RemoveSink() {
56  --m_numSinks;
57  NumSinksChanged();
58  }
59 
60  // Functions to keep track of the number of sinks connected to this source
61  // that are "enabled", in other words, listening for new images. Primarily
62  // used by sources to determine whether they should actually bother trying
63  // to get source frames.
64  int GetNumSinksEnabled() const { return m_numSinksEnabled; }
65 
66  void EnableSink() {
67  ++m_numSinksEnabled;
68  NumSinksEnabledChanged();
69  }
70 
71  void DisableSink() {
72  --m_numSinksEnabled;
73  NumSinksEnabledChanged();
74  }
75 
76  // Gets the current frame time (without waiting for a new one).
77  uint64_t GetCurFrameTime();
78 
79  // Gets the current frame (without waiting for a new one).
80  Frame GetCurFrame();
81 
82  // Blocking function that waits for the next frame and returns it.
83  Frame GetNextFrame();
84 
85  // Blocking function that waits for the next frame and returns it (with
86  // timeout in seconds). If timeout expires, returns empty frame.
87  Frame GetNextFrame(double timeout);
88 
89  // Force a wakeup of all GetNextFrame() callers by sending an empty frame.
90  void Wakeup();
91 
92  // Property functions
93  int GetPropertyIndex(wpi::StringRef name) const;
94  wpi::ArrayRef<int> EnumerateProperties(wpi::SmallVectorImpl<int>& vec,
95  CS_Status* status) const;
96  CS_PropertyKind GetPropertyKind(int property) const;
97  wpi::StringRef GetPropertyName(int property, wpi::SmallVectorImpl<char>& buf,
98  CS_Status* status) const;
99  int GetProperty(int property, CS_Status* status) const;
100  virtual void SetProperty(int property, int value, CS_Status* status) = 0;
101  int GetPropertyMin(int property, CS_Status* status) const;
102  int GetPropertyMax(int property, CS_Status* status) const;
103  int GetPropertyStep(int property, CS_Status* status) const;
104  int GetPropertyDefault(int property, CS_Status* status) const;
105  wpi::StringRef GetStringProperty(int property,
107  CS_Status* status) const;
108  virtual void SetStringProperty(int property, wpi::StringRef value,
109  CS_Status* status) = 0;
110  std::vector<std::string> GetEnumPropertyChoices(int property,
111  CS_Status* status) const;
112 
113  // Standard common camera properties
114  virtual void SetBrightness(int brightness, CS_Status* status) = 0;
115  virtual int GetBrightness(CS_Status* status) const = 0;
116  virtual void SetWhiteBalanceAuto(CS_Status* status) = 0;
117  virtual void SetWhiteBalanceHoldCurrent(CS_Status* status) = 0;
118  virtual void SetWhiteBalanceManual(int value, CS_Status* status) = 0;
119  virtual void SetExposureAuto(CS_Status* status) = 0;
120  virtual void SetExposureHoldCurrent(CS_Status* status) = 0;
121  virtual void SetExposureManual(int value, CS_Status* status) = 0;
122 
123  // Video mode functions
124  VideoMode GetVideoMode(CS_Status* status) const;
125  virtual bool SetVideoMode(const VideoMode& mode, CS_Status* status) = 0;
126 
127  // These have default implementations but can be overridden for custom
128  // or optimized behavior.
129  virtual bool SetPixelFormat(VideoMode::PixelFormat pixelFormat,
130  CS_Status* status);
131  virtual bool SetResolution(int width, int height, CS_Status* status);
132  virtual bool SetFPS(int fps, CS_Status* status);
133 
134  std::vector<VideoMode> EnumerateVideoModes(CS_Status* status) const;
135 
136  std::unique_ptr<Image> AllocImage(VideoMode::PixelFormat pixelFormat,
137  int width, int height, size_t size);
138 
139  protected:
140  void PutFrame(VideoMode::PixelFormat pixelFormat, int width, int height,
141  wpi::StringRef data, Frame::Time time);
142  void PutFrame(std::unique_ptr<Image> image, Frame::Time time);
143  void PutError(wpi::StringRef msg, Frame::Time time);
144 
145  // Notification functions for corresponding atomics
146  virtual void NumSinksChanged() = 0;
147  virtual void NumSinksEnabledChanged() = 0;
148 
149  std::atomic_int m_numSinks{0};
150  std::atomic_int m_numSinksEnabled{0};
151 
152  protected:
153  // Get a property; must be called with m_mutex held.
154  PropertyImpl* GetProperty(int property) {
155  if (property <= 0 || static_cast<size_t>(property) > m_propertyData.size())
156  return nullptr;
157  return m_propertyData[property - 1].get();
158  }
159  const PropertyImpl* GetProperty(int property) const {
160  if (property <= 0 || static_cast<size_t>(property) > m_propertyData.size())
161  return nullptr;
162  return m_propertyData[property - 1].get();
163  }
164 
165  // Create an "empty" property. This is called by GetPropertyIndex to create
166  // properties that don't exist (as GetPropertyIndex can't fail).
167  // Note: called with m_mutex held.
168  virtual std::unique_ptr<PropertyImpl> CreateEmptyProperty(
169  wpi::StringRef name) const = 0;
170 
171  // Cache properties. Implementations must return false and set status to
172  // CS_SOURCE_IS_DISCONNECTED if not possible to cache.
173  virtual bool CacheProperties(CS_Status* status) const = 0;
174 
175  void NotifyPropertyCreated(int propIndex, PropertyImpl& prop);
176 
177  // Update property value; must be called with m_mutex held.
178  void UpdatePropertyValue(int property, bool setString, int value,
179  wpi::StringRef valueStr);
180 
181  // Cached properties and video modes (protected with m_mutex)
182  mutable std::vector<std::unique_ptr<PropertyImpl>> m_propertyData;
183  mutable wpi::StringMap<int> m_properties;
184  mutable std::vector<VideoMode> m_videoModes;
185  // Current video mode
186  mutable VideoMode m_mode;
187  // Whether CacheProperties() has been successful at least once (and thus
188  // should not be called again)
189  mutable std::atomic_bool m_properties_cached{false};
190 
191  mutable wpi::mutex m_mutex;
192 
193  private:
194  void ReleaseImage(std::unique_ptr<Image> image);
195  std::unique_ptr<Frame::Impl> AllocFrameImpl();
196  void ReleaseFrameImpl(std::unique_ptr<Frame::Impl> data);
197 
198  std::string m_name;
199  std::string m_description;
200 
201  wpi::mutex m_frameMutex;
202  wpi::condition_variable m_frameCv;
203 
204  bool m_destroyFrames{false};
205 
206  // Pool of frames/images to reduce malloc traffic.
207  wpi::mutex m_poolMutex;
208  std::vector<std::unique_ptr<Frame::Impl>> m_framesAvail;
209  std::vector<std::unique_ptr<Image>> m_imagesAvail;
210 
211  std::atomic_bool m_connected{false};
212 
213  // Most recent frame (returned to callers of GetNextFrame)
214  // Access protected by m_frameMutex.
215  // MUST be located below m_poolMutex as the Frame destructor calls back
216  // into SourceImpl::ReleaseImage, which locks m_poolMutex.
217  Frame m_frame;
218 };
219 
220 } // namespace cs
221 
222 #endif // CSCORE_SOURCEIMPL_H_
Definition: CvSourceImpl.h:19
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:41
Definition: SourceImpl.h:30
Definition: PropertyImpl.h:21
bool IsConnected(NT_Inst inst)
Return whether or not the instance is connected to another node.
Definition: ntcore_cpp.cpp:904
Definition: Frame.h:27
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Video mode.
Definition: cscore_cpp.h:46