Valkka  0.17.0
OpenSource Video Management
sharedmem.h
Go to the documentation of this file.
1 #ifndef sharedmem_HEADER_GUARD
2 #define sharedmem_HEADER_GUARD
3 /*
4  * sharedmem.h : Posix shared memory segment server/client management, shared memory ring buffer synchronized using posix semaphores.
5  *
6  * Copyright 2017, 2018 Valkka Security Ltd. and Sampsa Riikonen.
7  *
8  * Authors: Sampsa Riikonen <sampsa.riikonen@iki.fi>
9  *
10  * This file is part of the Valkka library.
11  *
12  * Valkka is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Affero General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Affero General Public License for more details.
21  *
22  * You should have received a copy of the GNU Affero General Public License
23  * along with this program. If not, see <https://www.gnu.org/licenses/>
24  *
25  */
26 
37 #include "common.h"
38 #include <sys/shm.h>
39 #include <sys/mman.h>
40 #include <sys/stat.h> /* For mode constants */
41 #include <fcntl.h> /* For O_* constants */
42 #include <semaphore.h> // semaphores
43 #include "framefilter.h"
44 #include "Python.h"
45 
46 
49 class EventFd { // <pyapi>
50 
51 public: // <pyapi>
52  EventFd(); // <pyapi>
53  ~EventFd(); // <pyapi>
54 
55 private:
56  int fd;
57 
58 public: // <pyapi>
59  int getFd(); // <pyapi>
60 }; // <pyapi>
61 
62 
75 // https://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file
77 
78 public:
86  SharedMemSegment(const char* name, std::size_t n_bytes, bool is_server=false);
88  virtual ~SharedMemSegment();
89 
90 protected:
91  virtual void serverInit() = 0;
92  virtual bool clientInit() = 0;
93  virtual void serverClose() = 0;
94  virtual void clientClose() = 0;
95 
96 public:
97  virtual std::size_t getSize() = 0;
98 
99  virtual void put(std::vector<uint8_t> &inp_payload, void *meta_) = 0;
100  virtual void put(uint8_t* buf_, void* meta_) = 0;
101 
102  virtual void copyMetaFrom(void *meta_) = 0;
103  virtual void copyMetaTo(void *meta_) = 0;
104 
105 protected:
106  std::string name;
107  std::string payload_name;
108  std::string meta_name;
109  bool is_server;
110  void *ptr,*ptr_;
112 
113 public:
114  uint8_t *payload;
115  // void *meta; ///< Metadata (define in child classes);
116  std::size_t n_bytes;
117 
118 public: // client
119  void init();
120  void close_();
121  bool getClientState();
122 };
123 
124 
130 
131 public:
132  SimpleSharedMemSegment(const char* name, std::size_t n_bytes, bool is_server=false);
133  virtual ~SimpleSharedMemSegment();
134 
135 protected:
136  virtual void serverInit();
137  virtual bool clientInit();
138  virtual void serverClose();
139  virtual void clientClose();
140 
141 public:
142  virtual std::size_t getSize();
143 
144  /* virtual method, since metadata depends on the shared mem segment type */
145  virtual void put(std::vector<uint8_t> &inp_payload, void* meta_);
146  virtual void put(uint8_t* buf_, void* meta_);
147  virtual void putAVRGBFrame(AVRGBFrame *f);
148 
149  virtual void copyMetaFrom(void *meta_);
150  virtual void copyMetaTo(void *meta_);
151 
152 public:
153  std::size_t *meta;
154 
155 public:
156  void put(std::vector<uint8_t> &inp_payload);
157 
158 };
159 
160 
165 struct RGB24Meta { // <pyapi>
166  std::size_t size;
167  int width; // <pyapi>
168  int height; // <pyapi>
169  SlotNumber slot; // <pyapi>
170  long int mstimestamp; // <pyapi>
171 }; // <pyapi>
172 
173 
180 
181 public:
182  RGB24SharedMemSegment(const char* name, int width, int height, bool is_server=false);
183  virtual ~RGB24SharedMemSegment();
184 
185 protected:
186  virtual void serverInit();
187  virtual bool clientInit();
188  virtual void serverClose();
189  virtual void clientClose();
190 
191 public:
192  virtual std::size_t getSize();
193 
194  virtual void put(std::vector<uint8_t> &inp_payload, void* meta_);
195  virtual void put(uint8_t* buf_, void* meta_);
196  virtual void putAVRGBFrame(AVRGBFrame *f);
197 
198  virtual void copyMetaFrom(void *meta_);
199  virtual void copyMetaTo(void *meta_);
200 
201 public:
202  RGB24Meta *meta;
203 
204 };
205 
206 
217 class SharedMemRingBufferBase { // <pyapi>
218 
219 public: // <pyapi>
231  SharedMemRingBufferBase(const char* name, int n_cells, std::size_t n_bytes, int mstimeout=0, bool is_server=false); // <pyapi>
233  virtual ~SharedMemRingBufferBase(); // <pyapi>
234 
235 protected: // at constructor init list
236  std::string name;
237  int n_cells, n_bytes;
238  int mstimeout;
239  bool is_server;
240 
241 protected: // posix semaphores and mmap'd files
242  sem_t *sema, *flagsema;
243  std::string sema_name;
244  std::string flagsema_name;
245  int index;
246  struct timespec ts;
247  int fd;
248 
249 public:
250  std::vector<SharedMemSegment*> shmems;
251 
252 protected: // internal methods - not for the api user
253  void setFlag();
254  bool flagIsSet();
255  void clearFlag();
256  int getFlagValue();
257  void zero();
258  void setEventFd();
259  void clearEventFd();
260 
261 
262 public:
263  int getValue();
264  bool getClientState();
265 
266 public: // server side routines - call these only from the server // <pyapi>
273  void serverPush(std::vector<uint8_t> &inp_payload, void* meta);
275  void serverUseFd(EventFd &event_fd); // <pyapi>
276 
277 
278 public: // client side routines - call only from the client side // <pyapi>
288  bool clientPull(int &index_out, void* meta); // <pyapi>
290  bool clientPullThread(int &index_out, void* meta); // <pyapi>
291  PyObject *getBufferListPy(); // <pyapi>
293  void clientUseFd(EventFd &event_fd); // <pyapi>
294 }; // <pyapi>
295 
296 
297 
298 class SharedMemRingBuffer : public SharedMemRingBufferBase { // <pyapi>
299 
300 public: // <pyapi>
301  SharedMemRingBuffer(const char* name, int n_cells, std::size_t n_bytes, int mstimeout=0, bool is_server=false); // <pyapi>
303  virtual ~SharedMemRingBuffer(); // <pyapi>
304 
305 public: // <pyapi>
306  void serverPush(std::vector<uint8_t> &inp_payload); // <pyapi>
307  bool clientPull(int &index_out, int &size_out); // <pyapi>
308 }; // <pyapi>
309 
310 
311 
317 
318 public: // <pyapi>
320  SharedMemRingBufferRGB(const char* name, int n_cells, int width, int height, int mstimeout=0, bool is_server=false); // <pyapi>
322  virtual ~SharedMemRingBufferRGB(); // <pyapi>
323 
324 protected:
325  int width, height;
326 
327 public:
328  void serverPushAVRGBFrame(AVRGBFrame *f);
329 
330 public: // <pyapi>
334  // PyObject* clientPullPy(); // <pyapi>
336  bool clientPull(int &index_out, int &size_out); // <pyapi>
338  bool clientPullFrame(int &index_out, RGB24Meta &meta); // <pyapi>
340  bool clientPullFrameThread(int &index_out, RGB24Meta &meta); // <pyapi>
341  bool serverPushPyRGB(PyObject *po, SlotNumber slot, long int mstimestamp); // <pyapi>
342 }; // <pyapi>
343 
344 
345 
351 class ShmemFrameFilter : public FrameFilter { // <pyapi>
352 
353 public: // <pyapi>
364  ShmemFrameFilter(const char* name, int n_cells, std::size_t n_bytes, int mstimeout=0); // <pyapi>
365  //~ShmemFrameFilter(); // <pyapi>
366 
367 protected: // initialized at constructor
368  //int n_cells;
369  //std::size_t n_bytes;
370  //int mstimeout;
371  SharedMemRingBuffer shmembuf;
372 
373 protected:
374  virtual void go(Frame* frame);
375 
376 public: // <pyapi>
377  void useFd(EventFd &event_fd); // <pyapi>
378 }; // <pyapi>
379 
380 
386 class RGBShmemFrameFilter : public FrameFilter { // <pyapi>
387 
388 public: // <pyapi>
391  RGBShmemFrameFilter(const char* name, int n_cells, int width, int height, int mstimeout=0); // <pyapi>
392  //~RGBShmemFrameFilter(); // <pyapi>
393 
394 protected: // initialized at constructor
395  //int n_cells;
396  //int width;
397  //int height;
398  //int mstimeout;
399  SharedMemRingBufferRGB shmembuf;
400 
401 protected:
402  virtual void go(Frame* frame);
403 
404 public: // <pyapi>
405  void useFd(EventFd &event_fd); // <pyapi>
406 }; // <pyapi>
407 
408 
409 #endif
Interprocess shared memory ring buffer synchronized with posix semaphores.
Definition: sharedmem.h:217
std::vector< SharedMemSegment * > shmems
Shared memory segments.
Definition: sharedmem.h:250
A file descriptor for running select and poll with shmem ring buffers.
Definition: sharedmem.h:49
std::string payload_name
Name to identify the posix memory mapped file.
Definition: sharedmem.h:107
Shared memory segment with metadata (the segment size)
Definition: sharedmem.h:76
uint8_t * payload
Pointer to payload.
Definition: sharedmem.h:114
A Shmem segment describing an RGB24 frame.
Definition: sharedmem.h:179
A seriazable metadata object.
Definition: sharedmem.h:165
std::size_t size
Actual size copied // <pyapi>
Definition: sharedmem.h:166
std::string flagsema_name
Name to identify the posix semaphore used for the overflow flag.
Definition: sharedmem.h:244
Definition: sharedmem.h:298
int index
The index of cell that has just been written. Remember: server and client see their own copies of thi...
Definition: sharedmem.h:245
Like ShmemFrameFilter.
Definition: sharedmem.h:386
std::string meta_name
Name to identify the posix memory mapped file for the metadata.
Definition: sharedmem.h:108
void * ptr_
Raw pointers to shared memory.
Definition: sharedmem.h:110
This FrameFilter writes frames into a SharedMemRingBuffer.
Definition: sharedmem.h:351
std::size_t n_bytes
Maximum size of the payload (this much is reserved)
Definition: sharedmem.h:116
std::string sema_name
Name to identify the posix semaphore counter.
Definition: sharedmem.h:243
SharedMemRingBuffer for AVRGBFrame.
Definition: sharedmem.h:316
bool is_server
Are we on the server side or not?
Definition: sharedmem.h:239
Definition of FrameFilter and derived classes for various purposes.
bool is_server
Client or server process?
Definition: sharedmem.h:109
Decoded YUV frame in a non-planar format (thus "NP")
Definition: frame.h:430
int fd
A file descriptor for poll and select.
Definition: sharedmem.h:247
bool client_state
Was the shmem acquisition succesfull?
Definition: sharedmem.h:111
Frame: An abstract queueable class.
Definition: frame.h:108
List of common header files.
std::string name
Name to identify the posix objects.
Definition: sharedmem.h:106
The mother class of all frame filters! FrameFilters are used to create "filter chains".
Definition: framefilter.h:46
int n_bytes
Parameters defining the shmem ring buffer (number, size)
Definition: sharedmem.h:237
int mstimeout
Semaphore timeout in milliseconds.
Definition: sharedmem.h:238
sem_t * flagsema
Posix semaphore objects (semaphore counter, semaphore for the overflow flag)
Definition: sharedmem.h:242
Shared mem segment with simple metadata : just the payload length.
Definition: sharedmem.h:129