ccRTP 2.1.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rtphello.cpp
Go to the documentation of this file.
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...
35 #include <ccrtp/rtp.h>
36 
37 #ifdef CCXX_NAMESPACES
38 using namespace ost;
39 using namespace std;
40 #endif
41 
42 // base ports
43 const int RECEIVER_BASE = 33634;
44 const int TRANSMITTER_BASE = 32522;
45 
46 // For this example, this is irrelevant.
47 //const int TIMESTAMP_RATE = 90000;
48 
53 class ccRTP_Hello_Rx: public Thread
54 {
55 
56 private:
57  // socket to receive packets
59  // loopback network address
60  InetHostAddress local_ip;
61  // identifier of this sender
62  uint32 ssrc;
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
81  socket = new RTPSession(local_ip,RECEIVER_BASE);
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.
94  void run(void){
95 
96  cout << "Hello, " << defaultApplication().
97  getSDESItem(SDESItemTypeCNAME)
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);
104  if( !socket->addDestination(local_ip,TRANSMITTER_BASE) )
105  cerr << "Rx (" << hex << (int)ssrc
106  << "): could not connect to port."
107  << TRANSMITTER_BASE;
108 
109  cout << "Rx (" << hex << (int)ssrc
110  << "): " << local_ip.getHostname()
111  << " is waiting for salutes in port "
112  << RECEIVER_BASE << "..." << endl;
113 
114  socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
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.
127  const AppDataUnit *adu = NULL;
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 << "]: "
140  << adu->getData() << endl;
141  delete adu;
142  }
143  }
144 };
145 
150 class ccRTP_Hello_Tx: public Thread, public TimerPort
151 {
152 
153 private:
154  // socket to transmit
156  // loopback network address
157  InetHostAddress local_ip;
158  // identifier of this sender
159  uint32 ssrc;
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 
176  socket = new RTPSession(local_ip,TRANSMITTER_BASE);
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.
189  void run(void){
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);
199  if( !socket->addDestination(local_ip,RECEIVER_BASE) )
200  cerr << "Tx (" << hex << (int)ssrc
201  << "): could not connect to port."
202  << RECEIVER_BASE;
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.
213  socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
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.
261  ccRTP_Hello_Rx *receiver = new ccRTP_Hello_Rx;
262  ccRTP_Hello_Tx *transmitter = new ccRTP_Hello_Tx;
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 
const int RECEIVER_BASE
Definition: rtphello.cpp:43
Interface (envelope) to data received over RTP packets.
Definition: queuebase.h:68
Canonical end-point identifier.
Definition: rtcppkt.h:67
void run(void)
Definition: rtphello.cpp:189
InetHostAddress local_ip
Definition: rtphello.cpp:157
Transmitter of salutes.
Definition: rtphello.cpp:150
SingleThreadRTPSession RTPSession
Uses two pairs of sockets for RTP data and RTCP transmission/reception.
Definition: rtp.h:601
Receiver of salutes.
Definition: rtphello.cpp:53
const int TRANSMITTER_BASE
Definition: rtphello.cpp:44
RTPSession * socket
Definition: rtphello.cpp:58
RTPSession * socket
Definition: rtphello.cpp:155
This template class adds the threading aspect to the RTPSessionBase template in one of the many possi...
Definition: rtp.h:418
Static payload format objects.
Definition: formats.h:200
int main(int argc, char *argv[])
Definition: rtphello.cpp:257
const uint8 *const getData() const
Get data as it is received in RTP packets (i.e.
Definition: queuebase.h:105
MPEG 2 Transport stream (RFCs 1890, 2250)
Definition: formats.h:108
InetHostAddress local_ip
Definition: rtphello.cpp:60
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...
Definition: source.cpp:128
void run(void)
Definition: rtphello.cpp:94