1 // rtphello
2 // A very simple program for testing and illustrating basic features of ccRTP.
3 // Copyright (C) 2001-2015 Federico Montesino <fedemp@altern.org>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20 // This is an introductory example file that illustrates basic usage
21 // of ccRTP. You will also see a bit on how to use other classes from
22 // CommonC++.
23
24 // I am a typical hello world program. I consist of a sender thread,
25 // that sends the salutation message on RTP packets; and a receiver
26 // thread, that prints the messages. This is a program with an unsual
27 // structure, the receiver just tries to process the first available
28 // packet periodically, and both are in the same program. Thus, it
29 // should not be seen as an example for typical applications but as a
30 // test of some functions of ccRTP.
31
32 #include <cstdio>
33 #include <ctime>
34 // In order to use ccRTP, the RTP stack of CommonC++, just include...
36
37 #ifdef CCXX_NAMESPACES
38 using namespace ost;
39 using namespace std;
40 #endif
41
42 // base ports
45
46 // For this example, this is irrelevant.
47 //const int TIMESTAMP_RATE = 90000;
48
54 {
55
56 private:
57 // socket to receive packets
59 // loopback network address
61 // identifier of this sender
63
64 public:
66 // Before using ccRTP you should learn something about other
67 // CommonC++ classes. We need InetHostAddress...
68
69 // Construct loopback address
70 local_ip = "127.0.0.1";
71
72 // Is that correct?
73 if( ! local_ip ){
74 // this is equivalent to `! local_ip.isInetAddress()'
75 cerr << "Rx: IP address is not correct!" << endl;
76 exit();
77 }
78
79 // create socket for RTP connection and get a random
80 // SSRC identifier
82 ssrc = socket->getLocalSSRC();
83 }
84
86 cout << endl << "Destroying receiver -ID: " << hex
87 << (int)ssrc;
88 terminate();
89 delete socket;
90 cout << "... " << "destroyed.";
91 }
92
93 // This method does almost everything.
95
98 << " ..." << endl;
99 // redefined from Thread.
100 // Set up connection
101 socket->setSchedulingTimeout(20000);
102 socket->setExpireTimeout(3000000);
103 //socket->UDPTransmit::setTypeOfService(SOCKET_IPTOS_LOWDELAY);
105 cerr << "Rx (" << hex << (int)ssrc
106 << "): could not connect to port."
108
109 cout << "Rx (" << hex << (int)ssrc
110 << "): " << local_ip.getHostname()
111 << " is waiting for salutes in port "
113
115 socket->startRunning();
116 // Let's check the queues (you should read the documentation
117 // so that you know what the queues are for).
118 cout << "Rx (" << hex << (int)ssrc
119 << "): The queue is "
120 << ( socket->isActive() ? "" : "in")
121 << "active." << endl;
122
123 // This is the main loop, where packets are received.
124 for( int i = 0 ; true ; i++ ){
125
126 // Wait for an RTP packet.
128 while ( NULL == adu ) {
129 Thread::sleep(10);
130 adu = socket->
getData(socket->getFirstTimestamp());
131 }
132
133 // Print content (likely a salute :))
134 // Note we are sure the data is an asciiz string.
135 time_t receiving_time = time(NULL);
136 char tmstring[30];
137 strftime(tmstring,30,"%X",localtime(&receiving_time));
138 cout << "Rx (" << hex << (int)ssrc
139 << "): [receiving at " << tmstring << "]: "
141 delete adu;
142 }
143 }
144 };
145
151 {
152
153 private:
154 // socket to transmit
156 // loopback network address
158 // identifier of this sender
160
161 public:
163 // Before using ccRTP you should learn something about other
164 // CommonC++ classes. We need InetHostAddress...
165
166 // Construct loopback address
167 local_ip = "127.0.0.1";
168
169 // Is that correct?
170 if( ! local_ip ){
171 // this is equivalent to `! local_ip.isInetAddress()'
172 cerr << "Tx: IP address is not correct!" << endl;
173 exit();
174 }
175
177 ssrc = socket->getLocalSSRC();
178 }
179
181 cout << endl << "Destroying transmitter -ID: " << hex
182 << (int)ssrc;
183 terminate();
184 delete socket;
185 cout << "... " << "destroyed.";
186 }
187
188 // This method does almost everything.
190 // redefined from Thread.
191 cout << "Tx (" << hex << (int)ssrc << "): " <<
192 local_ip.getHostname()
193 << " is going to salute perself through "
194 << local_ip << "..." << endl;
195
196 // Set up connection
197 socket->setSchedulingTimeout(20000);
198 socket->setExpireTimeout(3000000);
200 cerr << "Tx (" << hex << (int)ssrc
201 << "): could not connect to port."
203
204 cout << "Tx (" << hex << (int)ssrc <<
205 "): Transmitting salutes to port "
206 << RECEIVER_BASE << "..." << endl;
207
208 uint32 timestamp = 0;
209 // This will be useful for periodic execution
210 TimerPort::setTimer(1000);
211
212 // This is the main loop, where packets are sent.
214 socket->startRunning();
215 // Let's check the queues (you should read the documentation
216 // so that you know what the queues are for).
217 cout << "Tx (" << hex << (int)ssrc << "): The queue is "
218 << ( socket->isActive()? "" : "in")
219 << "active." << endl;
220
221 for( int i = 0 ; true ;i++ ){
222
223 // send RTP packets, providing timestamp,
224 // payload type and payload.
225 // construct salute.
226 unsigned char salute[50];
227 snprintf((char *)salute,50,
228 "Hello, brave gnu world (#%u)!",i);
229 time_t sending_time = time(NULL);
230 // get timestamp to send salute
231 if ( 0 == i ){
232 timestamp = socket->getCurrentTimestamp();
233
234 } else {
235 // increment for 1 second
236 timestamp += socket->getCurrentRTPClockRate();
237 }
238
239 socket->putData(timestamp,salute,
240 strlen((char *)salute)+1);
241 // print info
242 char tmstring[30];
243 strftime(tmstring,30,"%X",
244 localtime(&sending_time));
245 cout << "Tx (" << hex << (int)ssrc
246 << "): sending salute " << "no " << dec << i
247 << ", at " << tmstring
248 << "..." << endl;
249
250 // Let's wait for the next cycle
251 Thread::sleep(TimerPort::getTimer());
252 TimerPort::incTimer(1000);
253 }
254 }
255 };
256
257 int main(
int argc,
char *argv[])
258 {
259
260 // Construct the two main threads. they will not run yet.
263
264 cout << "This is rtphello, a very simple test program for ccRTP." <<
265 endl << "Strike [Enter] when you are fed up with it." << endl;
266
267 // Start execution of hello now.
268 receiver->start();
269 transmitter->start();
270
271 cin.get();
272
273 delete transmitter;
274 delete receiver;
275
276 cout << endl << "That's all." << endl;
277
278 return 0;
279 }
280
Interface (envelope) to data received over RTP packets.
Canonical end-point identifier.
SingleThreadRTPSession RTPSession
Uses two pairs of sockets for RTP data and RTCP transmission/reception.
const int TRANSMITTER_BASE
This template class adds the threading aspect to the RTPSessionBase template in one of the many possi...
int main(int argc, char *argv[])
const uint8 *const getData() const
Get data as it is received in RTP packets (i.e.
MPEG 2 Transport stream (RFCs 1890, 2250)
Generic and audio/video profile specific RTP interface of ccRTP.
__EXPORT RTPApplication & defaultApplication()
Get the RTPApplication object for the "default" application (the only one used by common applications...