Valkka  0.17.0
OpenSource Video Management
livethread.h
Go to the documentation of this file.
1 #ifndef LIVETHREAD_HEADER_GUARD
2 #define LIVETHREAD_HEADER_GUARD
3 /*
4  * livethread.h : A live555 thread
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 "live.h"
38 #include "liveserver.h"
39 #include "thread.h"
40 #include "framefilter.h"
41 #include "framefifo.h"
42 
43 
44 void setLiveOutPacketBuffermaxSize(unsigned i); // <pyapi>
45 
46 
56 class LiveFifo : public FrameFifo {
57 
58 public:
60  LiveFifo(const char* name, FrameFifoContext ctx);
62  ~LiveFifo();
63 
64 protected:
65  void* live_thread;
66 
67 public:
68  void setLiveThread(void* live_thread);
69  bool writeCopy(Frame* f, bool wait=false);
70 };
71 
72 
79 enum class LiveConnectionType { // <pyapi>
80  none, // <pyapi>
81  rtsp, // <pyapi>
82  sdp // <pyapi>
83 }; // <pyapi>
84 
85 
96 struct LiveConnectionContext { // <pyapi>
98  LiveConnectionContext(LiveConnectionType ct, std::string address, SlotNumber slot, // <pyapi>
99  FrameFilter* framefilter) : // <pyapi>
100  connection_type(ct), address(address), slot(slot), framefilter(framefilter), msreconnect(0), // <pyapi>
101  request_multicast(false), request_tcp(false), recv_buffer_size(0), reordering_time(0), // <pyapi>
102  time_correction(TimeCorrectionType::smart) // <pyapi>
103  {} // <pyapi>
105  LiveConnectionContext() : // <pyapi>
106  connection_type(LiveConnectionType::none), address(""), slot(0), framefilter(NULL), msreconnect(0), // <pyapi>
107  request_multicast(false), request_tcp(false),time_correction(TimeCorrectionType::smart) // <pyapi>
108  {} // <pyapi>
110  std::string address;
111  SlotNumber slot;
113  long unsigned int msreconnect;
115  bool request_tcp;
116  unsigned recv_buffer_size;
117  unsigned reordering_time;
119 }; // <pyapi>
120 
121 
126 struct LiveOutboundContext { // <pyapi>
127  LiveOutboundContext(LiveConnectionType ct, std::string address, SlotNumber slot, // <pyapi>
128  unsigned short int portnum) : // <pyapi>
129  connection_type(ct), address(address), slot(slot), portnum(portnum), ttl(225) // <pyapi>
130  {} // <pyapi>
131  LiveOutboundContext() : // <pyapi>
132  connection_type(LiveConnectionType::none), address(""), slot(0), portnum(0), ttl(255) // <pyapi>
133  {} // <pyapi>
135  std::string address;
136  SlotNumber slot;
137  unsigned short int portnum;
138  unsigned char ttl;
139 }; // <pyapi>
140 
141 
142 
148 enum class LiveSignal {
149  none,
150  exit,
151  // inbound streams
152  register_stream,
153  deregister_stream,
154  play_stream,
155  stop_stream,
156  // outbound streams
157  register_outbound,
158  deregister_outbound
159 };
160 
161 
167  LiveConnectionContext *connection_context;
168  LiveOutboundContext *outbound_context;
169 };
170 
171 
172 
184 class Connection {
185 
186 public:
194  Connection(UsageEnvironment& env, LiveConnectionContext& ctx);
195  virtual ~Connection();
196 
197 protected:
199 
200  // internal framefilter chain.. if we'd like to modify the frames before they are passed to the API user
201  // more framefilters could be generated here and initialized in the constructor init list
202  // the starting filter should always be named as "inputfilter" .. this is where Live555 writes the frames
203  // TimestampFrameFilter2 timestampfilter; ///< Internal framefilter: correct timestamp
204  // SlotFrameFilter inputfilter; ///< Internal framefilter: set slot number
205 
206  FrameFilter* timestampfilter;
207  FrameFilter* inputfilter;
209 
210  long int frametimer;
211 
212 public:
213  UsageEnvironment &env;
214  bool is_playing;
215 
216 public:
217  virtual void playStream() =0;
218  virtual void stopStream() =0;
219  virtual void reStartStream();
220  virtual void reStartStreamIf();
221  virtual bool isClosed();
222  virtual void forceClose();
223  SlotNumber getSlot();
224 };
225 
226 
235 class Outbound { // will leave this quite generic .. don't know at this point how the rtsp server is going to be // analogy: AVThread
236 
237 public:
238  Outbound(UsageEnvironment& env, FrameFifo& fifo, LiveOutboundContext& ctx);
239  virtual ~Outbound();
240 
241 public: // init'd at constructor time
243  UsageEnvironment &env;
245 
246 protected:
247  bool setup_ok, at_setup;
248 
249 public:
250  virtual void reinit();
251  virtual void handleFrame(Frame *f);
252 };
253 
254 
261 class RTSPConnection : public Connection {
262 
263 public:
265  RTSPConnection(UsageEnvironment& env, LiveConnectionContext& ctx);
266  ~RTSPConnection();
267  // RTSPConnection(const RTSPConnection& cp); ///< Copy constructor .. nopes, default copy constructor good enough
268 
269 
270 private:
273 
274 public:
275  void playStream();
276  void stopStream();
277  void reStartStreamIf();
278  bool isClosed();
279  void forceClose();
280 };
281 
282 
287 class SDPConnection : public Connection {
288 
289 public:
291  SDPConnection(UsageEnvironment& env, LiveConnectionContext& ctx);
293  ~SDPConnection();
294 
295 private:
296  StreamClientState *scs;
297 
298 public:
299  void playStream();
300  void stopStream();
301 
302 };
303 
304 
313 class SDPOutbound : public Outbound {
314 
315 public:
316  SDPOutbound(UsageEnvironment &env, FrameFifo &fifo, LiveOutboundContext& ctx);
317  ~SDPOutbound();
318 
319 public: // virtual redefined
320  void reinit();
321  void handleFrame(Frame *f);
322 
323 public:
324  std::vector<Stream*> streams;
325 };
326 
327 
336 class RTSPOutbound : public Outbound {
337 
338 public:
339  RTSPOutbound(UsageEnvironment &env, RTSPServer &server, FrameFifo &fifo, LiveOutboundContext& ctx);
340  ~RTSPOutbound();
341 
342 protected: // init'd at constructor time
343  RTSPServer &server;
344 
345 public: // virtual redefined
346  void reinit();
347  void handleFrame(Frame *f);
348 
349 public:
350  ServerMediaSession *media_session;
351  std::vector<ValkkaServerMediaSubsession*> media_subsessions;
352 
353 };
354 
355 
356 
368 class LiveThread : public Thread { // <pyapi>
369 
370 public:
371  static void periodicTask(void* cdata);
372 
373 public: // <pyapi>
380  LiveThread(const char* name, FrameFifoContext fifo_ctx=FrameFifoContext()); // <pyapi>
381  ~LiveThread(); // <pyapi>
382 
383 protected: // frame input
386 
387 protected: // redefinitions
388  std::deque<LiveSignalContext> signal_fifo;
389 
390 protected:
391  TaskScheduler* scheduler;
392  UsageEnvironment* env;
394  std::vector<Connection*> slots_;
395  std::vector<Outbound*> out_slots_;
396  std::list<Connection*> pending;
398  EventTriggerId event_trigger_id_hello_world;
399  EventTriggerId event_trigger_id_frame_arrived;
400  EventTriggerId event_trigger_id_got_frames;
401  int fc;
402 
403 protected: // rtsp server for live and/or recorded stream
404  UserAuthenticationDatabase *authDB;
405  RTSPServer *server;
406 
407 public: // redefined virtual functions
408  void run();
409  void preRun();
410  void postRun();
412  void sendSignal(LiveSignalContext signal_ctx);
413 
414 protected:
415  void handlePending();
416  void checkAlive();
417  void closePending();
418  void handleSignals();
419  void handleFrame(Frame* f);
420 
421 private: // internal
422  int safeGetSlot (SlotNumber slot, Connection*& con);
423  int safeGetOutboundSlot (SlotNumber slot, Outbound*& outbound);
424  // inbound streams
425  void registerStream (LiveConnectionContext &connection_ctx);
426  void deregisterStream (LiveConnectionContext &connection_ctx);
427  void playStream (LiveConnectionContext &connection_ctx);
428  // outbound streams
429  void registerOutbound (LiveOutboundContext &outbound_ctx);
430  void deregisterOutbound (LiveOutboundContext &outbound_ctx);
431  // thread control
432  void stopStream (LiveConnectionContext &connection_ctx);
433 
434 public: // *** C & Python API *** .. these routines go through the condvar/mutex locking // <pyapi>
435  // inbound streams
436  void registerStreamCall (LiveConnectionContext &connection_ctx);
437  void deregisterStreamCall (LiveConnectionContext &connection_ctx);
438  void playStreamCall (LiveConnectionContext &connection_ctx);
439  void stopStreamCall (LiveConnectionContext &connection_ctx);
440  // outbound streams
441  void registerOutboundCall (LiveOutboundContext &outbound_ctx);
442  void deregisterOutboundCall (LiveOutboundContext &outbound_ctx);
443  // thread control
444  void requestStopCall();
445  // LiveFifo &getFifo(); ///< API method: get fifo for sending frames with live555 // <pyapi>
446  FifoFrameFilter &getFrameFilter();
447  void setRTSPServer(int portnum=8554);
448 
449 public: // live555 events and tasks
450  static void helloWorldEvent(void* clientData);
451  static void frameArrivedEvent(void* clientData);
452  static void gotFramesEvent(void* clientData);
453  static void readFrameFifoTask(void* clientData);
454 
455 public:
456  void testTrigger();
457  void triggerGotFrames();
458 }; // <pyapi>
459 
460 #endif
UsageEnvironment & env
UsageEnvironment identifying the Live555 event loop (see Live555 primer)
Definition: livethread.h:213
Describes the stack structure and fifo behaviour for a FrameFifo.
Definition: framefifo.h:45
LiveFifo(const char *name, FrameFifoContext ctx)
Default constructor.
Definition: livethread.cpp:49
A negotiated RTSP connection.
Definition: livethread.h:261
signal to AVThread or OpenGLThread. Also custom signals to custom Threads
Thread safe system of fifo and a stack.
Same as LiveConnectionContext, but for outbound streams (i.e.
Definition: livethread.h:126
long unsigned int msreconnect
If stream has delivered nothing during this many milliseconds, reconnect // <pyapi> ...
Definition: livethread.h:113
FrameFifo & fifo
Outgoing fFrames are being read and finally recycled here.
Definition: livethread.h:244
unsigned char ttl
Packet time-to-live // <pyapi>
Definition: livethread.h:138
FifoFrameFilter infilter
A FrameFilter for writing incoming frames.
Definition: livethread.h:385
FrameFilter * framefilter
The frames are feeded into this FrameFilter // <pyapi>
Definition: livethread.h:112
Identifies a stream and encapsulates information about the type of connection the user is requesting ...
Definition: livethread.h:96
SlotNumber slot
A unique stream slot that identifies this stream // <pyapi>
Definition: livethread.h:136
A thread-safe combination of a fifo (first-in-first-out) queue and an associated stack.
Definition: framefifo.h:72
std::deque< LiveSignalContext > signal_fifo
Redefinition of signal fifo (Thread::signal_fifo becomes hidden)
Definition: livethread.h:388
LiveOutboundContext & ctx
Identifies the connection type, stream address, etc. See LiveOutboundContext.
Definition: livethread.h:242
TimeCorrectionType
Methods to correct frame timestamps.
Definition: frame.h:83
Live555 interface for server side: streaming to udp sockets directly or by using an on-demand rtsp se...
unsigned short int portnum
Start port number (for sdp) // <pyapi>
Definition: livethread.h:137
Class to hold per-stream state that we maintain throughout each stream&#39;s lifetime.
Definition: live.h:78
TimeCorrectionType time_correction
How to perform frame timestamp correction // <pyapi>
Definition: livethread.h:118
undefined (initial value)
Definition: usbthread.h:143
std::string address
Stream address // <pyapi>
Definition: livethread.h:110
Sending a stream without rtsp negotiation (i.e.
Definition: livethread.h:313
This is a special FrameFifo class for feeding frames into live555, i.e.
Definition: livethread.h:56
LiveConnectionContext(LiveConnectionType ct, std::string address, SlotNumber slot, FrameFilter *framefilter)
Default constructor.
Definition: livethread.h:98
UsageEnvironment & env
Identifies the live555 event loop.
Definition: livethread.h:243
LiveConnectionType connection_type
Identifies the connection type // <pyapi>
Definition: livethread.h:134
LiveFifo infifo
A FrameFifo for incoming frames.
Definition: livethread.h:384
char eventLoopWatchVariable
Modifying this, kills the Live555 event loop.
Definition: livethread.h:393
SlotNumber slot
A unique stream slot that identifies this stream // <pyapi>
Definition: livethread.h:111
Base class for multithreading.
LiveStatus livestatus
Reference of this variable is passed to ValkkaRTSPClient. We can see outside of the live555 callback ...
Definition: livethread.h:272
unsigned reordering_time
Live555 packet reordering treshold time (microsecs) // <pyapi>
Definition: livethread.h:117
std::vector< Stream * > streams
SubStreams of the outgoing streams (typically two, e.g. video and sound)
Definition: livethread.h:324
RTSPServer & server
Reference to the RTSPServer instance.
Definition: livethread.h:343
Sending a stream using the on-demand rtsp server.
Definition: livethread.h:336
bool writeCopy(Frame *f, bool wait=false)
Take a frame "ftmp" from the stack, copy contents of "f" into "ftmp" and insert "ftmp" into the begin...
Definition: livethread.cpp:61
std::vector< Connection * > slots_
A constant sized vector. Book-keeping of the connections (RTSP or SDP) currently active in the live55...
Definition: livethread.h:394
long int frametimer
Measures time when the last frame was received.
Definition: livethread.h:210
FrameFifoContext ctx
Parameters defining the stack and overflow behaviour.
Definition: framefifo.h:82
LiveStatus
Status for the ValkkaRTSPClient.
Definition: live.h:62
ValkkaRTSPClient * client
ValkkaRTSPClient defines the behaviour (i.e. event registration and callbacks) of the RTSP client (se...
Definition: livethread.h:271
bool request_multicast
Request multicast in the rtsp negotiation or not // <pyapi>
Definition: livethread.h:114
Fifo fifo
The fifo queue.
Definition: framefifo.h:87
Live555, running in a separate thread.
Definition: livethread.h:368
LiveConnectionContext()
Dummy constructor : remember to set member values by hand.
Definition: livethread.h:105
FrameFilter * repeat_sps_filter
Repeat sps & pps packets before i-frame (if they were not there before the i-frame) ...
Definition: livethread.h:208
Handles a live555 RTSP connection.
Definition: live.h:111
UsageEnvironment * env
Live555 UsageEnvironment identifying the event loop.
Definition: livethread.h:392
Identifies the information the signals LiveThread::Signals carry.
Definition: livethread.h:165
LiveSignal
Characteristic signals for the Live555 thread.
Definition: livethread.h:148
Definition of FrameFilter and derived classes for various purposes.
Interface to live555.
A class for multithreading with a signaling system.
Definition: thread.h:90
std::list< Connection * > pending
Incoming connections pending for closing.
Definition: livethread.h:396
int fc
debugging: incoming frame counter
Definition: livethread.h:401
Frame: An abstract queueable class.
Definition: frame.h:108
LiveConnectionType connection_type
Identifies the connection type // <pyapi>
Definition: livethread.h:109
Passes frames to a FrameFifo.
Definition: framefilter.h:560
A base class that unifies all kinds of outgoing streams (i.e.
Definition: livethread.h:235
unsigned recv_buffer_size
Operating system ringbuffer size for incoming socket // <pyapi>
Definition: livethread.h:116
Connection is is defined in an SDP file.
Definition: livethread.h:287
TaskScheduler * scheduler
Live555 event loop TaskScheduler.
Definition: livethread.h:391
bool exit_requested
Exit asap.
Definition: livethread.h:397
bool request_tcp
Request interleaved rtsp streaming or not // <pyapi>
Definition: livethread.h:115
The mother class of all frame filters! FrameFilters are used to create "filter chains".
Definition: framefilter.h:46
~LiveFifo()
Default virtual destructor.
Definition: livethread.cpp:52
bool at_setup
Flags used by Outbound::handleFrame.
Definition: livethread.h:247
std::string address
Stream address // <pyapi>
Definition: livethread.h:135
A base class that unifies all kinds of connections (RTSP and SDP).
Definition: livethread.h:184
LiveConnectionContext & ctx
LiveConnectionContext identifying the stream source (address), it&#39;s destination (slot and target fram...
Definition: livethread.h:198
LiveConnectionType
LiveThread connection types.
Definition: livethread.h:79
std::vector< Outbound * > out_slots_
Book-keeping for the outbound connections.
Definition: livethread.h:395