Instrument Neutral Distributed Interface INDI  2.0.2
streammanager_p.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020 by Pawel Soja <kernel32.pl@gmail.com>
3  Copyright (C) 2015 by Jasem Mutlaq <mutlaqja@ikarustech.com>
4  Copyright (C) 2014 by geehalel <geehalel@gmail.com>
5 
6  Stream Recorder
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 */
23 
24 #pragma once
25 
26 #include "indiapi.h"
28 #include "encoder/encodermanager.h"
29 #include "fpsmeter.h"
30 #include "uniquequeue.h"
31 #include "gammalut16.h"
32 
33 #include <atomic>
34 #include <string>
35 #include <map>
36 #include <thread>
37 
38 #include "indiccdchip.h"
39 #include "indisensorinterface.h"
40 
41 /* Smart Widget-Property */
42 #include "indipropertytext.h"
43 #include "indipropertynumber.h"
44 #include "indipropertyswitch.h"
45 #include "indipropertyblob.h"
46 namespace INDI
47 {
48 
50 {
51  public:
52  struct FrameInfo
53  {
54  size_t x, y, w, h;
55  size_t bytesPerColor;
56 
58  : x(0)
59  , y(0)
60  , w(0)
61  , h(0)
62  , bytesPerColor(0)
63  { }
64 
65  explicit FrameInfo(const CCDChip &ccdChip, size_t bytesPerColor = 1)
66  : x(ccdChip.getSubX() / ccdChip.getBinX())
67  , y(ccdChip.getSubY() / ccdChip.getBinY())
68  , w(ccdChip.getSubW() / ccdChip.getBinX())
69  , h(ccdChip.getSubH() / ccdChip.getBinY())
71  { }
72 
73  explicit FrameInfo(const SensorInterface &sensorInterface, size_t bytesPerColor = 1)
74  : x(0)
75  , y(0)
76  , w(sensorInterface.getBufferSize() * 8 / sensorInterface.getBPS())
77  , h(1)
79  { }
80 
81  size_t pixels() const
82  {
83  return w * h;
84  }
85 
86  size_t totalSize() const
87  {
88  return w * h * bytesPerColor;
89  }
90 
91  size_t lineSize() const
92  {
93  return w * bytesPerColor;
94  }
95 
96  bool operator!=(const FrameInfo &other) const
97  {
98  return other.x != x || other.y != y || other.w != w || other.h != h;
99  }
100  };
101  public:
102  StreamManagerPrivate(DefaultDevice *defaultDevice);
103  virtual ~StreamManagerPrivate();
104 
105  public:
106  bool initProperties();
107  void ISGetProperties(const char *dev);
108 
109  bool ISNewText(const char * dev, const char * name, char * texts[], char * names[], int n);
110  bool ISNewSwitch(const char * dev, const char * name, ISState * states, char * names[], int n);
111  bool ISNewNumber(const char * dev, const char * name, double values[], char * names[], int n);
112 
113  void newFrame(const uint8_t * buffer, uint32_t nbytes, uint64_t timestamp);
114 
115  bool updateProperties();
116  bool setStream(bool enable);
117 
118  const char *getDeviceName() const;
119 
120  void setSize(uint16_t width, uint16_t height);
121  bool setPixelFormat(INDI_PIXEL_FORMAT pixelFormat, uint8_t pixelDepth);
122 
126  void asyncStreamThread();
127 
128  // helpers
129  static std::string expand(const std::string &fname, const std::map<std::string, std::string> &patterns);
130 
131  // Utility for record file
132  bool startRecording();
133 
134  // Stop recording. Force stop even in abnormal state if needed.
135  bool stopRecording(bool force = false);
136 
143  bool uploadStream(const uint8_t *buffer, uint32_t nbytes);
144 
149  bool recordStream(const uint8_t *buffer, uint32_t nbytes, double deltams, uint64_t timestamp);
150 
151  void getStreamFrame(uint16_t * x, uint16_t * y, uint16_t * w, uint16_t * h) const;
152  void setStreamFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
153  void setStreamFrame(const FrameInfo &frameInfo);
154 
155  FrameInfo updateSourceFrameInfo();
156 
157  static void subframe(
158  const uint8_t *srcBuffer,
159  const FrameInfo &srcFrameInfo,
160  uint8_t *dstBuffer,
161  const FrameInfo &dstFrameInfo
162  );
163 
164  public:
166 
168 
169  /* Stream switch */
171 
173 
174  /* Record switch */
176  enum
177  {
181  RECORD_OFF
182  };
183 
184  /* Record File Info */
186 
188  enum
189  {
192  };
193 
194  /* Measured FPS */
197 
198  /* Record Options */
200 
201  // Stream Frame
203 
204  /* BLOBs */
206 
207  // Encoder Selector. It's static now but should this implemented as plugin interface?
210 
211  // Recorder Selector. Static but should be implmeneted as a dynamic plugin interface
214 
215  // Limits. Maximum queue size for incoming frames. FPS Limit for preview
218 
219  std::atomic<bool> isStreaming { false };
220  std::atomic<bool> isRecording { false };
221  std::atomic<bool> isRecordingAboutToClose { false };
222  bool hasStreamingExposure { true };
223 
224  // Recorder
227  bool direct_record = false;
228  std::string recordfiledir, recordfilename; /* in case we should move it */
229 
230  // Encoders
233 
234  // Measure FPS
239 
240  uint32_t frameCountDivider = 0;
241 
243  uint8_t PixelDepth = 8;
244  uint16_t rawWidth = 0, rawHeight = 0;
245  std::string Format;
246 
247  // Processing for streaming
248  typedef struct
249  {
250  double time;
251  uint64_t timestamp;
252  std::vector<uint8_t> frame;
253  } TimeFrame;
254 
255  std::thread framesThread; // async incoming frames processing
256  std::atomic<bool> framesThreadTerminate {false};
258 
259  std::mutex fastFPSUpdate;
260  std::mutex recordMutex;
261 
263 };
264 
265 }
The CCDChip class provides functionality of a CCD Chip within a CCD.
Definition: indiccdchip.h:35
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
The EncoderInterface class is the base class for video streaming encoders.
The EncoderManager class contains a list of active supported encoders.
Provides generic container for INDI properties.
Definition: indiproperty.h:48
The RecorderInterface class is the base class for recorders.
The RecorderManager class contains a list of active supported recorders.
The SensorDevice class provides functionality of a Sensor Device within a Sensor.
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
std::atomic< bool > isRecording
bool setPixelFormat(INDI_PIXEL_FORMAT pixelFormat, uint8_t pixelDepth)
INDI::PropertySwitch RecordStreamSP
static std::string expand(const std::string &fname, const std::map< std::string, std::string > &patterns)
void setStreamFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
INDI::PropertySwitch EncoderSP
std::atomic< bool > isStreaming
INDI::PropertySwitch StreamSP
static void subframe(const uint8_t *srcBuffer, const FrameInfo &srcFrameInfo, uint8_t *dstBuffer, const FrameInfo &dstFrameInfo)
void newFrame(const uint8_t *buffer, uint32_t nbytes, uint64_t timestamp)
std::atomic< bool > isRecordingAboutToClose
bool stopRecording(bool force=false)
UniqueQueue< TimeFrame > framesIncoming
INDI::PropertyBlob imageBP
std::atomic< bool > framesThreadTerminate
INDI::PropertyNumber RecordOptionsNP
EncoderInterface * encoder
const char * getDeviceName() const
INDI::PropertyNumber StreamTimeNP
INDI::PropertyNumber FpsNP
void setSize(uint16_t width, uint16_t height)
bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
bool uploadStream(const uint8_t *buffer, uint32_t nbytes)
uploadStream Upload frame to client using the selected encoder
INDI_PIXEL_FORMAT PixelFormat
RecorderManager recorderManager
bool recordStream(const uint8_t *buffer, uint32_t nbytes, double deltams, uint64_t timestamp)
recordStream Calls the backend recorder to record a single frame.
RecorderInterface * recorder
INDI::PropertyText RecordFileTP
INDI::PropertyNumber StreamFrameNP
INDI::PropertyNumber LimitsNP
StreamManagerPrivate(DefaultDevice *defaultDevice)
void getStreamFrame(uint16_t *x, uint16_t *y, uint16_t *w, uint16_t *h) const
void asyncStreamThread()
Thread processing frames and forwarding to recording and preview.
void ISGetProperties(const char *dev)
bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
INDI::PropertyNumber StreamExposureNP
INDI::PropertySwitch RecorderSP
The UniqueQueue class is a thread-safe FIFO container adapter.
Definition: uniquequeue.h:36
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
ISState
Switch state.
Definition: indiapi.h:150
INDI_PIXEL_FORMAT
Definition: indibasetypes.h:70
@ INDI_MONO
Definition: indibasetypes.h:71
std::vector< uint8_t > buffer
Namespace to encapsulate INDI client, drivers, and mediator classes.
bool operator!=(const FrameInfo &other) const
FrameInfo(const SensorInterface &sensorInterface, size_t bytesPerColor=1)
FrameInfo(const CCDChip &ccdChip, size_t bytesPerColor=1)