CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

RtpReceiver.cpp
Go to the documentation of this file.
1 //
2 // RtpReceiver.cpp -- a unit generator that listens on an RTP socket for incoming audio buffers.
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5
6 #include "RtpReceiver.h"
7
8 using namespace csl;
9
10 #ifdef RTP_TIMING
11 static struct timeval then, now; // used for getting the real time
12 static long timeVals, thisSec, timeSum; // for printing run-time statistics
13 #endif
14
15 // RtpReceiver Constructor: socket-code heavy lifting
16 // Open up a remote frame stream using a socket to the given remote "server" ip/host
17
18 RtpReceiver :: RtpReceiver(unsigned chans)
19 : mNumChans(chans),
20 mBufferFrames(RTP_BUFFER_SIZE),
21 CslRtpSession(mNumChans, mBufferFrames),
22 mRtpMutex()
23 {
24 // The constructor should set up all of the transmission and session params, but
25 // should not do anything related to specific addresses
26
27 // Create instances of our RTP classes
28 mTransparams = new RTPUDPv4TransmissionParams;
29 mSessparams = new RTPSessionParams;
30
31 #ifdef CSL_WINDOWS
32 //MUST call WSAStartup() to use WS2_32.DLL
33 WSADATA wsaData;
34 if (WSAStartup(MAKEWORD( 2, 2 ), &wsaData)!= 0) //WSACleanup called in destructor
35 perror("Couldn't do WSAStartup");
36 #endif
37
38 // create the RTP session, but don't add any destinations yet
39 // Note that this also creates the thread that polls for incoming RTP packets
40 if (!createRtpSession()) goto error;
41
42 return;
43 error:
44 logMsg(kLogError, "RtpReceiver init error");
45 return;
46 }
47
48 // Destructor
49
50 RtpReceiver :: ~RtpReceiver() {
51
52 BYEDestroy(RTPTime(10,0),0,0); // Destroy the RTP session (wait 10 seconds for acknowledgement)
53
54 if (mTransparams) delete mTransparams;
55 if (mSessparams) delete mSessparams;
56 if (mAddress) delete mAddress;
57
58 #ifdef CSL_WINDOWS
59 WSACleanup(); // Must be called because WSAStartup() called in class constructor
60 #endif
61 }
62
63 bool RtpReceiver :: createRtpSession() {
64
65 mSessparams->SetOwnTimestampUnit(1.0/mFrameRate); // Our timestamp is 1/Fs
66 mSessparams->SetUsePollThread(TRUE); // This is the default behavior, but let's be verbose
67
68 <<<<<<< RtpReceiver.cpp
69 mRtpSession->SetDefaultPayloadType(11); // Default payload is a mono 16/44.1 stream (type 11)
70 mRtpSession->SetDefaultMark(false); // Sets the default marker to false
71 mRtpSession->SetDefaultTimestampIncrement((unsigned) (CGestalt::frameRate() * 0.020)); // Default is 20 ms of samples per packet
72 =======
73 SetDefaultPayloadType(11); // Default payload is a mono 16/44.1 stream (type 11)
74 SetDefaultMark(false); // Sets the default marker to false
75 SetDefaultTimestampIncrement(CGestalt::frameRate() * 0.020); // Default is 20 ms of samples per packet
76 >>>>>>> 1.5
77
78 mTransparams->SetPortbase(mLocalPort);
79 int status = Create(*mSessparams,mTransparams);
80 printError(status);
81 return true;
82 }
83
84 bool RtpReceiver :: addRtpSource(char * remoteIP, unsigned short remotePort) {
85
86 mAddress = new RTPIPv4Address;
87
88 // The inet_addr function returns a value in network byte order, but
89 // we need the IP address in host byte order, so we use a call to
90 // ntohl
91 mRemoteIP = inet_addr(remoteIP);
92 mRemoteIP = ntohl(mRemoteIP);
93
94 // Storing passed parameters to class members
95 mRemotePort = remotePort;
96
97 // Set the IP and port of the address we receive data from
98 mAddress->SetIP(mRemoteIP);
99 mAddress->SetPort(mRemotePort);
100
101 int status = AddDestination(*mAddress); // Adds a destination to the RTP stream (potential for multicasting)
102 printError(status);
103 return true;
104 }
105
106 bool RtpReceiver :: removeRtpSource() {
107 // Destroy the RTP session, say bye to the server
108 DeleteDestination(*mAddress);
109 return true;
110 }
111
112 void RtpReceiver:: printError(int rtperr)
113 {
114 if (rtperr < 0)
115 {
116 string errStr = "Error: " + RTPGetErrorString(rtperr) + "\n";
117
118 // We need to convert the string to a char * before passing
119 // it to logMsg...
120 char * logStr = new char[errStr.length()+1];
121 strcpy(logStr, errStr.c_str());
122
123 logMsg(kLogError, logStr);
124 exit(-1);
125 }
126 }
127
128 //// nextBuffer method -- copy data and signal the semaphore when you need more ////
129 // TODO: This should actually deal with multi-channel nextBuffer calls, and support multi-channel RTP
130
131 void RtpReceiver :: nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (Exception)
132 {
133 float * outputBufferPtr = outputBuffer.monoBuffer(outBufNum);
134 unsigned char * out, * buf;
135 unsigned numFramesRequested = outputBuffer.mNumFrames;
136 unsigned toCopy; // # of bytes to copy per channel
137 unsigned offset;
138
139 mRtpMutex.lock();
140
141 // TODO: multiple channels
142
143 if (mBufferState == kBuffering) { // If we haven't started playback yet (still buffering from an underrun)
144 memset(outputBufferPtr, 0, numFramesRequested * sizeof(sample)); // Fill outBuf with zeroes
145 mRtpMutex.unlock();
146 return;
147 }
148
149 // Read the next part of rBuff ring buffer into outputBuffer
150 mRtpBuffer.nextBuffer(outputBuffer);
151 mRtpMutex.unlock();
152
153 return;
154 }