CSL  5.2
RtpSender.cpp
Go to the documentation of this file.
1 //
2 // RemoteIO.cpp -- CSL I/O Port for sending sample buffers out over sockets
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "RtpSender.h"
7 
8 using namespace csl;
9 
10 // Constructor
11 
12 RtpSender :: RtpSender(unsigned chans)
13  : Effect(),
14  mNumChans(chans),
15  mBufferFrames(RTP_BUFFER_SIZE),
17  mRtpMutex()
18 {
19 // The constructor should set up all of the transmission and session params, but
20 // should not do anything related to specific addresses
21 
22  mLastPacketNumber = -1; // We haven't received a packet yet, so -1 indicates this
23 
24  mPayloadType = 11; // Default payload is a mono 16/44.1 stream (type 11)
25  SetDefaultPayloadType(mPayloadType); // And set it in the session
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, "RtpSender init error");
45  return;
46 }
47 
48 // Destructor
49 
51  BYEDestroy(RTPTime(10,0),0,0); // Destroy the RTP session (wait 10 seconds for acknowledgement)
52 
53  if (mTransparams) delete mTransparams;
54  if (mSessparams) delete mSessparams;
55  if (mAddress) delete mAddress;
56 
57  #ifdef CSL_WINDOWS
58  WSACleanup(); // Must be called because WSAStartup() called in class constructor
59  #endif
60 }
61 
63 
64  mSessparams->SetOwnTimestampUnit(1.0/mFrameRate); // Our timestamp is 1/Fs
65  mSessparams->SetUsePollThread(TRUE); // This is the default behavior, but let's be verbose
66 
67 <<<<<<< RtpSender.cpp
68  mRtpSession->SetDefaultPayloadType(11); // Default payload is a mono 16/44.1 stream (type 11)
69  mRtpSession->SetDefaultMark(false); // Sets the default marker to false
70  mRtpSession->SetDefaultTimestampIncrement((unsigned) (CGestalt::frameRate() * 0.020)); // Default is 20 ms of samples per packet
71 =======
72  SetDefaultMark(false); // Sets the default marker to false
73  SetDefaultTimestampIncrement(CGestalt::frameRate() * 0.020); // Default is 20 ms of samples per packet
74 >>>>>>> 1.4
75 
76  mTransparams->SetPortbase(mLocalPort);
77  int status = Create(*mSessparams,mTransparams); // Create the RTP Session
78  printError(status);
79  return true;
80 }
81 
82 bool RtpSender :: addRtpDestination(char * remoteIP, unsigned short remotePort) {
83 
84  mAddress = new RTPIPv4Address;
85 
86  // The inet_addr function returns a value in network byte order, but
87  // we need the IP address in host byte order, so we use a call to
88  // ntohl
89  mRemoteIP = inet_addr(remoteIP);
90  mRemoteIP = ntohl(mRemoteIP);
91 
92  // Storing passed parameters to class members
93  mRemotePort = remotePort;
94 
95  // Set the IP and port of the address we receive data from
96  mAddress->SetIP(mRemoteIP);
97  mAddress->SetPort(mRemotePort);
98 
99  int status = AddDestination(*mAddress); // Adds a destination to the RTP stream (potential for multicasting)
100  printError(status);
101  return true;
102 }
103 
105  // Destroy the RTP session, say bye to the server
106  DeleteDestination(*mAddress);
107  return true;
108 }
109 
110 void RtpSender :: printError(int rtperr)
111 {
112  if (rtperr < 0)
113  {
114  string errStr = "Error: " + RTPGetErrorString(rtperr) + "\n";
115 
116  // We need to convert the string to a char * before passing
117  // it to logMsg...
118  char * logStr = new char[errStr.length()+1];
119  strcpy(logStr, errStr.c_str());
120 
121  logMsg(kLogError, logStr);
122  exit(-1);
123  }
124 }
125 
126 void RtpSender :: nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (Exception)
127 // This nextBuffer function call should get the input buffer, put the data in RtpSender's
128 // internal RingBuffer, and echo the data to the outputBuffer
129 // TODO: This should actually deal with multi-channel nextBuffer calls, and support multi-channel RTP
130 {
131  if (outBufNum != 0) return; // We want to work with the multi-channel buffers only
132 
133  Port * inPort = mInputs[CSL_INPUT_L];
134  this->pullInput(inPort, outputBuffer.mNumFrames);
135  mInputPtr = inPort->mBuffer->mMonoBuffers[0];
136 // UnitGenerator :: nextBuffer(outputBuffer);
137 
138  sample * outputPtr = outputBuffer.monoBuffer(outBufNum);
139  sample * inputPtr = mInputPtr;
140  unsigned numFrames = outputBuffer.mNumFrames;
141 
142  outputBuffer.copySamplesFrom(*(this->inPort()->mBuffer)); // Copy input to output
143 // mRtpBuffer.writeBuffer(*(this->inPort()->mBuffer)); // And put the inputBuffer onto RtpBuffer
144  // TODO: the writeBuffer function NEEDS to return a buffer status indicator, or an int representing
145  // the actual # of samples written
146 
147  return;
148 }