blob: d8aa239d8b6d867df14def7e4dd235d937205697 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2001,2002,2004 Federico Montesino Pouzols <fedemp@altern.org>.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16//
17// As a special exception, you may use this file as part of a free software
18// library without restriction. Specifically, if other files instantiate
19// templates or use macros or inline functions from this file, or you compile
20// this file and link it with other files to produce an executable, this
21// file does not by itself cause the resulting executable to be covered by
22// the GNU General Public License. This exception does not however
23// invalidate any other reasons why the executable file might be covered by
24// the GNU General Public License.
25//
26// This exception applies only to the code released under the name GNU
27// ccRTP. If you copy code from other releases into a copy of GNU
28// ccRTP, as the General Public License permits, the exception does
29// not apply to the code that you add in this way. To avoid misleading
30// anyone as to the status of such modified files, you must delete
31// this exception notice from them.
32//
33// If you write modifications of your own for GNU ccRTP, it is your choice
34// whether to permit this exception to apply to your modifications.
35// If you do not wish that, delete this exception notice.
36//
37
38/**
39 * @file ioqueue.h
40 *
41 * @short Generic RTP input/output queues.
42 **/
43
44#ifndef CCXX_RTP_IOQUEUE_H_
45#define CCXX_RTP_IOQUEUE_H_
46
47#include <ccrtp/iqueue.h>
48#include <ccrtp/oqueue.h>
49
50#ifdef CCXX_NAMESPACES
51namespace ost {
52#endif
53
54/**
55 * @defgroup ioqueue Generic RTP input/output queues.
56 * @{
57 **/
58
59/**
60 * @class RTPDataQueue
61 *
62 * A packet queue handler for building different kinds of RTP protocol
63 * systems. The queue manages both incoming and outgoing RTP packets,
64 * as well as synchronization and transmission/reception timers. By
65 * making the queue handler a seperate base class it becomes possible
66 * to define RTP classes for RTP profiles and sessions of different
67 * types.
68 *
69 * Outgoing packets are sent via the OutgoingDataQueue::putData method.
70 *
71 * Incoming packets can be retrieved via IncomingDataQueue::getData
72 * method.
73 *
74 * @author David Sugar <dyfet@ostel.com>
75 * @short RTP data queue handler.
76 */
77class __EXPORT RTPDataQueue :
78 public IncomingDataQueue,
79 public OutgoingDataQueue
80{
81public:
82 /**
83 * @enum Tos rtp.h cc++/rtp.h
84 * @short Type of network service the application uses.
85 *
86 * If the application uses enhanced network service, for
87 * instance Integrated Services or Differentiated Services, it
88 * <em>has not</em> to ensure fair competition with TCP,
89 * provided that the requested service is actually being
90 * delivered. Whenever the application uses best-effort
91 * service or the requested enhanced service is not actually
92 * being delivered, it <em>has</em> to ensure fair competition
93 * with TCP. By default, best-effot is assumed.
94 *
95 * @note Although not required, RTP packets are always sent on
96 * top of UDP segments. No other underlying transport protocol
97 * is supported at present.
98 *
99 * @todo implement fair competition with tcp
100 **/
101 typedef enum {
102 tosBestEffort, ///< Best-effort network service
103 tosEnhanced ///< Enhanced network service
104 } Tos;
105
106 /**
107 * Specify the kind of service the application expects to use.
108 *
109 * @param tos type of service the application expects to use
110 *
111 * @note If enhanced service is specified but packet loss is
112 * high (the requested service does not appear to actually be
113 * delivered) ccRTP defaults to best-effort suitable
114 * behaviour: guarantee fair competition with TCP.
115 *
116 * @todo Implement fair competition with tcp
117 **/
118 inline void
119 setTypeOfService(Tos tos)
120 { typeOfService = tos; }
121
122 /**
123 * Enable packet queue processing in the stack. This method
124 * will not any thread of execution.
125 **/
126 inline void enableStack()
127 { dataServiceActive = true; }
128
129 /**
130 * Disable packet queue processing in the stack.
131 **/
132 inline void disableStack()
133 { dataServiceActive = false; }
134
135 /**
136 * Get active connection state flag.
137 *
138 * @return true if connection "active".
139 */
140 inline bool
141 isActive() const
142 { return dataServiceActive; }
143
144 /**
145 * Get the timestamp that should be given for a packet whose
146 * payload sampling instant corresponds to the current system
147 * time.
148 *
149 * The timestamp applications should provide for each packet
150 * represents the sampling instant of its payload and should
151 * not be a reading of the system clock. Nevertheless, the
152 * internal operation of the RTP stack relies on the accuracy
153 * of the provided timestamp, since several computations
154 * assume that there is a certain degree of correspondence
155 * between the timestamp and the system clock.
156 *
157 * It is recommended that applications use this method in
158 * order to <em>periodically adjust the RTP timestamp</em>.
159 *
160 * In particular, it is advisable getting the timestamp
161 * corresponding to the first sampling instant or any instant
162 * after a period of inactivity through a call to this method.
163 *
164 * Applications should use the nominal sampling or
165 * any other value provided by the coder in order to compute
166 * the next timestamps with minimum computational requirement.
167 *
168 * For instance, an application using an RTP profile that
169 * specifies a fixed sampling rate of 8 Khz with eight bits
170 * per sample, continuously transmitting audio blocks 80
171 * octets long, would transmit 100 packets every
172 * second. Every packet would carry a timestamp 80 units
173 * greater than the previous one. So, the first timestamp
174 * would be obtained from this method, whereas the following
175 * ones would be computed adding 80 every time. Also the
176 * timestamp should be increased for every block whether
177 * it is put in the queue or dropped.
178 *
179 * The aforementioned increment can be obtained from the
180 * RTPDataQueue::getTimestampIncrement() method rather than
181 * computing it by hand in the application.
182 *
183 * @note Frame based applications must follow a specific
184 * timestamping method, probably specified in a profile.
185 *
186 * @note You should take into account that by default ccRTP
187 * assumes that the application begins sampling at the queue
188 * creation time. Moreover, the first sampling instant is
189 * assigned a "user visible" timestamp of 0, although the RTP
190 * stack will then add internally a ramdom offset unknown to
191 * the application. That is to say, the application may count
192 * samples from 0 in order to get the timestamp for the next
193 * packet, provided that the first sampling instant is the
194 * same as the queue creation time. Nevertheless, this
195 * simpler way of starting will not be as accurate as it would
196 * be if the application got at least the first timestamp
197 * through getCurrentTimestamp. <em>We provide this option
198 * since ccRTP interface is evolving, but we admit that it is
199 * ugly, we could remove this option or even replace uint32
200 * timestamps with a restrictively regulated object;
201 * suggestions are gladly welcomed</em>
202 **/
203 uint32
204 getCurrentTimestamp() const;
205
206 /**
207 * Specify the bandwidth of the current session.
208 *
209 * @param bw bandwidth of the current session, in bits/s.
210 *
211 * @see AVPQueue::setControlBandwidth()
212 */
213 void
214 setSessionBandwidth(uint32 bw)
215 { sessionBw = bw; }
216
217 uint32
218 getDefaultSessionBandwidth() const
219 { return defaultSessionBw; }
220
221 uint32
222 getSessionBandwidth() const
223 { return sessionBw; }
224
225 /**
226 * Set the packet timeclock for synchronizing timestamps.
227 **/
228 inline void
229 setTimeclock()
230 { timeclock.setTimer(); }
231
232 /**
233 * Get the packet timeclock for synchronizing timestamps.
234 *
235 * @return runtime in milliseconds since last set.
236 */
237 inline timeout_t
238 getTimeclock() const
239 { return timeclock.getElapsed(); }
240
241protected:
242
243 /**
244 * Constructor. This will generate a random application SSRC
245 * identifier.
246 *
247 * @param size an estimation of the number of participants in
248 * the session
249 **/
250 RTPDataQueue(uint32 size = defaultMembersHashSize);
251
252 /**
253 * Using this constructor you can start a session with the
254 * given ssrc, instead of the usual randomly generated
255 * one. This is necessary when you need to initiate several
256 * sessions having the same SSRC identifier, for instance, to
257 * implement layered encoding, in which case each layer is
258 * managed through a different session but all sessions share
259 * the same SSRC identifier.
260 *
261 * @warning This doesn't seem to be a good solution
262 *
263 * @param ssrc Synchronization SouRCe identifier for this session
264 * @param size an estimation of the number of participants in the
265 * session
266 */
267 RTPDataQueue(uint32* ssrc, uint32 size = defaultMembersHashSize);
268
269 /**
270 * The queue destructor flushes the queue and stops all
271 * services.
272 */
273 inline virtual
274 ~RTPDataQueue()
275 { endQueue(); }
276
277 /**
278 * A plugin point for timer tick driven events.
279 */
280 inline virtual void
281 timerTick()
282 { return; }
283
284 void renewLocalSSRC()
285 {IncomingDataQueue::renewLocalSSRC();}
286
287private:
288 RTPDataQueue(const RTPDataQueue &o);
289
290 RTPDataQueue&
291 operator=(const RTPDataQueue &o);
292
293 /**
294 * Global queue initialization.
295 *
296 * @param localSSRC local 32-bit SSRC identifier
297 **/
298 void
299 initQueue();
300
301protected:
302 /**
303 * This method ends the queue.
304 */
305 void
306 endQueue();
307
308 /**
309 * This function is used to check for and schedule against
310 * arriving packets based on the derived connection type.
311 *
312 * @return true if packet waiting for processing.
313 * @param number of microseconds to wait.
314 */
315 virtual bool
316 isPendingData(microtimeout_t timeout) = 0;
317
318private:
319 // true if connection "active"
320 volatile bool dataServiceActive;
321 Tos typeOfService;
322 TimerPort timeclock;
323 /* RTP session bandwidth control */
324 static const uint32 defaultSessionBw;
325 uint32 sessionBw;
326
327
328};
329
330/** @}*/ // ioqueue
331
332#ifdef CCXX_NAMESPACES
333}
334#endif
335
336#endif //CCXX_RTP_IOQUEUE_H_
337
338/** EMACS **
339 * Local variables:
340 * mode: c++
341 * c-basic-offset: 8
342 * End:
343 */