00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <qapplication.h>
00010
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <errno.h>
00014 #include <iostream>
00015
00016 #ifndef WIN32
00017 #include <netinet/in.h>
00018 #include <linux/soundcard.h>
00019 #include <unistd.h>
00020 #include <fcntl.h>
00021 #include <sys/ioctl.h>
00022 #include <net/if.h>
00023 #include <linux/sockios.h>
00024 #include <mythtv/mythcontext.h>
00025 #include "config.h"
00026 #else
00027 #include <io.h>
00028 #include <winsock2.h>
00029 #include <sstream>
00030 #include <Dsound.h>
00031 #include "gcontext.h"
00032 #endif
00033
00034 #include "dtmffilter.h"
00035 #include "rtp.h"
00036 #include "g711.h"
00037
00038 using namespace std;
00039
00040
00041 rtp::rtp(QWidget *callingApp, int localPort, QString remoteIP, int remotePort, int mediaPay, int playout, int dtmfPay, QString micDev, QString spkDev, rtpTxMode txm, rtpRxMode rxm)
00042 {
00043 eventWindow = callingApp;
00044 yourIP.setAddress(remoteIP);
00045 myPort = localPort;
00046 myRtcpPort = localPort+1;
00047 yourPort = remotePort;
00048 yourRtcpPort = yourPort+1;
00049 txMode = txm;
00050 rxMode = rxm;
00051 if ((txMode == RTP_TX_VIDEO) || (rxMode == RTP_RX_VIDEO))
00052 {
00053 videoPayload = mediaPay;
00054 audioPayload = -1;
00055 dtmfPayload = -1;
00056 initVideoBuffers(10);
00057 pTxShaper = new TxShaper(28000, 1000, 50);
00058 }
00059 else
00060 {
00061 videoPayload = -1;
00062 audioPayload = mediaPay;
00063 dtmfPayload = dtmfPay;
00064 pTxShaper = 0;
00065 }
00066
00067
00068
00069 DTMFFilter = 0;
00070 if ((dtmfPayload == -1) && (audioPayload != -1) && (rxMode != RTP_RX_AUDIO_TO_SPEAKER))
00071 {
00072 DTMFFilter = new DtmfFilter();
00073 }
00074
00075
00076
00077 pkIn = 0;
00078 pkOut = 0;
00079 pkOutDrop = 0;
00080 pkMissed = 0;
00081 pkLate = 0;
00082 pkInDisc = 0;
00083 framesIn = 0;
00084 framesOut = 0;
00085 framesOutDiscarded = 0;
00086 framesInDiscarded = 0;
00087 txBuffer = 0;
00088 recBuffer = 0;
00089 dtmfIn = "";
00090 dtmfOut = "";
00091 videoToTx = 0;
00092 eventCond = 0;
00093 prevRxPkLost = 0;
00094 prevRxPkCnt = 0;
00095 rtcpFractionLoss = 0;
00096 rtcpTotalLoss = 0;
00097 peerSsrc = 0;
00098 timeNextRtcpTx = (QTime::currentTime()).addSecs(RTCP_PERIOD);
00099 adjustPlayoutDelay = 0;
00100 minPlayout = maxPlayout = -1;
00101 totPlayout = cntPlayout = 0;
00102 avgPlayout = 0;
00103 nominalPlayout = playout;
00104
00105 rtpInitialise();
00106
00107 audio = 0;
00108 if ((txMode == RTP_TX_AUDIO_FROM_MICROPHONE) && (rxMode == RTP_RX_AUDIO_TO_SPEAKER))
00109 {
00110 #ifdef WIN32
00111
00112
00113 audio = new dsAudioDriver(spkDev, micDev, txPCMSamplesPerPacket, callingApp->winId());
00114 #else
00115
00116
00117 if (spkDev == micDev)
00118 audio = new ossAudioDriver(spkDev, micDev, txPCMSamplesPerPacket);
00119 else
00120 audio = new mythAudioDriver(spkDev, micDev, txPCMSamplesPerPacket);
00121 #endif
00122 }
00123
00124 if (micDev == "None")
00125 txMode = RTP_TX_AUDIO_SILENCE;
00126
00127 killRtpThread = false;
00128 start(TimeCriticalPriority);
00129 }
00130
00131 rtp::~rtp()
00132 {
00133 killRtpThread = true;
00134 if (eventCond)
00135 eventCond->wakeAll();
00136 wait();
00137 destroyVideoBuffers();
00138 if (audio)
00139 delete audio;
00140 if (DTMFFilter)
00141 delete DTMFFilter;
00142 if (pTxShaper)
00143 delete pTxShaper;
00144 }
00145
00146 void rtp::rtpInitialise()
00147 {
00148 rtpSocket = 0;
00149 rtcpSocket = 0;
00150 rxMsPacketSize = 20;
00151 rxPCMSamplesPerPacket = rxMsPacketSize * PCM_SAMPLES_PER_MS;
00152 txMsPacketSize = 20;
00153 txPCMSamplesPerPacket = txMsPacketSize*PCM_SAMPLES_PER_MS;
00154 txSequenceNumber = 1;
00155 txTimeStamp = 0;
00156 txBuffer = 0;
00157 lastDtmfTimestamp = 0;
00158 dtmfIn = "";
00159 dtmfOut = "";
00160 recBuffer = 0;
00161 recBufferLen = 0;
00162 recBufferMaxLen = 0;
00163 rxFirstFrame = true;
00164 oobError = false;
00165 micMuted = false;
00166
00167 ToneToSpk = 0;
00168 ToneToSpkSamples = 0;
00169 ToneToSpkPlayed = 0;
00170
00171 pkIn = 0;
00172 pkOut = 0;
00173 pkOutDrop = 0;
00174 pkMissed = 0;
00175 pkLate = 0;
00176 pkInDisc = 0;
00177 bytesIn = 0;
00178 bytesOut = 0;
00179 bytesToSpeaker = 0;
00180 framesIn = 0;
00181 framesOut = 0;
00182 framesOutDiscarded = 0;
00183 rtcpFractionLoss = 0;
00184 rtcpTotalLoss = 0;
00185 micPower = 0;
00186 spkPower = 0;
00187 rxSeqNum = 0;
00188 rxFirstFrame = TRUE;
00189
00190 timeNextStatistics = QTime::currentTime().addSecs(RTP_STATS_INTERVAL);
00191 timeLastStatistics = timeLastRtcpStatistics = QTime::currentTime();
00192
00193
00194 pJitter = new Jitter();
00195
00196
00197 if (videoPayload != -1)
00198 {
00199 Codec = 0;
00200 rtpMPT = videoPayload;
00201 }
00202 else
00203 {
00204 if (audioPayload == RTP_PAYLOAD_G711U)
00205 Codec = new g711ulaw();
00206 else if (audioPayload == RTP_PAYLOAD_G711A)
00207 Codec = new g711alaw();
00208 #ifdef VA_G729
00209 else if (audioPayload == RTP_PAYLOAD_G729)
00210 Codec = new g729();
00211 #endif
00212 else if (audioPayload == RTP_PAYLOAD_GSM)
00213 Codec = new gsmCodec();
00214 else
00215 {
00216 cerr << "Unknown audio payload " << audioPayload << endl;
00217 audioPayload = RTP_PAYLOAD_G711U;
00218 Codec = new g711ulaw();
00219 }
00220
00221 rtpMPT = audioPayload;
00222 }
00223 rtpMarker = 0;
00224 }
00225
00226
00227 void rtp::run()
00228 {
00229 rtpThreadWorker();
00230 }
00231
00232
00233 void rtp::rtpThreadWorker()
00234 {
00235 if ((txMode == RTP_TX_VIDEO) || (rxMode == RTP_RX_VIDEO))
00236 rtpVideoThreadWorker();
00237 else
00238 rtpAudioThreadWorker();
00239 }
00240
00241 void rtp::rtpAudioThreadWorker()
00242 {
00243 RTPPACKET RTPpacket;
00244 QTime timeNextTx;
00245
00246 OpenSocket();
00247 if (audio)
00248 audio->Open();
00249
00250 timeNextTx = (QTime::currentTime()).addMSecs(rxMsPacketSize);
00251
00252 int pollLoop=0;
00253 int sleepMs = 0;
00254 while(!killRtpThread)
00255 {
00256
00257
00258
00259
00260 QTime t1 = QTime::currentTime();
00261 usleep(10000);
00262 sleepMs += t1.msecsTo(QTime::currentTime());
00263 pollLoop++;
00264
00265 if (killRtpThread)
00266 break;
00267
00268
00269 StreamInAudio();
00270
00271
00272 while (isSpeakerHungry() && !killRtpThread)
00273 PlayOutAudio();
00274
00275
00276 while ((txMode == RTP_TX_AUDIO_FROM_MICROPHONE) &&
00277 (audio->anyMicrophoneData()) &&
00278 (!killRtpThread))
00279 {
00280 if (fillPacketfromMic(RTPpacket))
00281 StreamOut(RTPpacket);
00282 }
00283
00284
00285
00286 if (((txMode == RTP_TX_AUDIO_SILENCE) || (txMode == RTP_TX_AUDIO_FROM_BUFFER)) &&
00287 (timeNextTx <= QTime::currentTime()))
00288 {
00289 timeNextTx = timeNextTx.addMSecs(rxMsPacketSize);
00290 switch (txMode)
00291 {
00292 default:
00293 case RTP_TX_AUDIO_SILENCE: fillPacketwithSilence(RTPpacket); break;
00294 case RTP_TX_AUDIO_FROM_BUFFER: fillPacketfromBuffer(RTPpacket); break;
00295 }
00296 StreamOut(RTPpacket);
00297 }
00298
00299 SendWaitingDtmf();
00300 RtcpSendReceive();
00301 CheckSendStatistics();
00302 }
00303
00304 if (audio)
00305 audio->Close();
00306 CloseSocket();
00307 if (pJitter)
00308 delete pJitter;
00309 if (Codec)
00310 delete Codec;
00311 if (ToneToSpk != 0)
00312 delete ToneToSpk;
00313
00314 if ((pollLoop != 0) && ((sleepMs/pollLoop)>30))
00315 cout << "Mythphone: \"sleep 10000\" is sleeping for more than 30ms; please report\n";
00316 }
00317
00318 void rtp::rtpVideoThreadWorker()
00319 {
00320 OpenSocket();
00321 eventCond = new QWaitCondition();
00322
00323
00324
00325
00326
00327
00328 while(!killRtpThread)
00329 {
00330
00331 usleep(10000);
00332
00333
00334 if (killRtpThread)
00335 break;
00336
00337 StreamInVideo();
00338 transmitQueuedVideo();
00339
00340 RtcpSendReceive();
00341 CheckSendStatistics();
00342 }
00343
00344
00345 delete eventCond;
00346 eventCond = 0;
00347
00348 if (videoToTx)
00349 {
00350 freeVideoBuffer(videoToTx);
00351 videoToTx = 0;
00352 }
00353
00354 VIDEOBUFFER *buf;
00355 while ((buf = rxedVideoFrames.take(0)) != 0)
00356 {
00357 freeVideoBuffer(buf);
00358 }
00359
00360 CloseSocket();
00361 if (pJitter)
00362 delete pJitter;
00363 if (Codec)
00364 delete Codec;
00365 }
00366
00367 void rtp::Debug(QString dbg)
00368 {
00369 #ifdef WIN32
00370 QString now = (QTime::currentTime()).toString("hh:mm:ss.zzz");
00371 if (eventWindow)
00372 QApplication::postEvent(eventWindow, new RtpEvent(RtpEvent::RtpDebugEv, now + " " + dbg));
00373 #else
00374 cout << dbg;
00375 #endif
00376 }
00377
00378 void rtp::CheckSendStatistics()
00379 {
00380 QTime now = QTime::currentTime();
00381 if (timeNextStatistics <= now)
00382 {
00383 int statsMsPeriod = timeLastStatistics.msecsTo(now);
00384 timeLastStatistics = now;
00385 timeNextStatistics = now.addSecs(RTP_STATS_INTERVAL);
00386 avgPlayout = (cntPlayout == 0) ? 0 : (totPlayout / cntPlayout);
00387 totPlayout = cntPlayout = 0;
00388 if (eventWindow)
00389 QApplication::postEvent(eventWindow,
00390 new RtpEvent(RtpEvent::RtpStatisticsEv, this, now, statsMsPeriod,
00391 pkIn, pkOut, pkMissed, pkLate, pkInDisc, pkOutDrop,
00392 bytesIn, bytesOut, bytesToSpeaker, framesIn, framesOut,
00393 framesInDiscarded, framesOutDiscarded,
00394 minPlayout == -1 ? 0 : minPlayout, avgPlayout,
00395 maxPlayout == -1 ? 0 : maxPlayout));
00396 }
00397 }
00398
00399 void rtp::SendRtcpStatistics()
00400 {
00401 QTime now = QTime::currentTime();
00402 int statsMsPeriod = timeLastRtcpStatistics.msecsTo(now);
00403 timeLastRtcpStatistics = now;
00404 if (eventWindow)
00405 QApplication::postEvent(eventWindow,
00406 new RtpEvent(RtpEvent::RtpRtcpStatsEv, this, now, statsMsPeriod,
00407 rtcpFractionLoss, rtcpTotalLoss));
00408 }
00409
00410 void rtp::OpenSocket()
00411 {
00412 rtpSocket = new QSocketDevice (QSocketDevice::Datagram);
00413 rtpSocket->setBlocking(false);
00414 rtpSocket->setSendBufferSize(49152);
00415 rtpSocket->setReceiveBufferSize(49152);
00416
00417 rtcpSocket = new QSocketDevice (QSocketDevice::Datagram);
00418 rtcpSocket->setBlocking(false);
00419
00420 #ifndef WIN32
00421 QString ifName = gContext->GetSetting("SipBindInterface");
00422 struct ifreq ifreq;
00423 strcpy(ifreq.ifr_name, ifName);
00424 if (ioctl(rtpSocket->socket(), SIOCGIFADDR, &ifreq) != 0)
00425 {
00426 cerr << "Failed to find network interface " << ifName << endl;
00427 delete rtpSocket;
00428 rtpSocket = 0;
00429 return;
00430 }
00431 struct sockaddr_in * sptr = (struct sockaddr_in *)&ifreq.ifr_addr;
00432 QHostAddress myIP;
00433 myIP.setAddress(htonl(sptr->sin_addr.s_addr));
00434 #endif
00435
00436 #ifdef WIN32 // SIOCGIFADDR not supported on Windows
00437 char hostname[100];
00438 HOSTENT FAR *hostAddr;
00439 int ifNum = atoi(gContext->GetSetting("SipBindInterface"));
00440 if ((gethostname(hostname, 100) != 0) || ((hostAddr = gethostbyname(hostname)) == NULL))
00441 {
00442 cerr << "Failed to find network interface " << endl;
00443 delete rtpSocket;
00444 rtpSocket = 0;
00445 return;
00446 }
00447 QHostAddress myIP;
00448 for (int ifTotal=0; hostAddr->h_addr_list[ifTotal] != 0; ifTotal++)
00449 ;
00450 if (ifNum >= ifTotal)
00451 ifNum = 0;
00452 myIP.setAddress(htonl(((struct in_addr *)hostAddr->h_addr_list[ifNum])->S_un.S_addr));
00453 #endif
00454
00455 if (!rtpSocket->bind(myIP, myPort))
00456 {
00457 cerr << "Failed to bind for RTP connection " << myIP.toString() << endl;
00458 delete rtpSocket;
00459 rtpSocket = 0;
00460 }
00461
00462 if (!rtcpSocket->bind(myIP, myRtcpPort))
00463 {
00464 cerr << "Failed to bind for RTCP connection " << myIP.toString() << endl;
00465 delete rtcpSocket;
00466 rtcpSocket = 0;
00467 }
00468 }
00469
00470
00471 void rtp::CloseSocket()
00472 {
00473 if (rtpSocket)
00474 {
00475 rtpSocket->close();
00476 delete rtpSocket;
00477 rtpSocket = 0;
00478 }
00479 if (rtcpSocket)
00480 {
00481 rtcpSocket->close();
00482 delete rtcpSocket;
00483 rtcpSocket = 0;
00484 }
00485 }
00486
00487 bool rtp::isSpeakerHungry()
00488 {
00489 if ((rxMode == RTP_RX_AUDIO_TO_SPEAKER) && (audio != 0))
00490 {
00491 if (rxFirstFrame)
00492 return false;
00493
00494
00495 if (audio->samplesOutSpaceRemaining() < rxPCMSamplesPerPacket)
00496 return false;
00497
00498
00499
00500 if (pJitter->isPacketQueued(rxSeqNum))
00501 return true;
00502
00503
00504
00505 if (audio->msOutQueued() < 15)
00506 return true;
00507 }
00508
00509 return false;
00510 }
00511
00512 void rtp::PlayToneToSpeaker(short *tone, int Samples)
00513 {
00514 if ((rxMode == RTP_RX_AUDIO_TO_SPEAKER) && (ToneToSpk == 0))
00515 {
00516 ToneToSpk = new short[Samples];
00517 memcpy(ToneToSpk, tone, Samples*sizeof(short));
00518 ToneToSpkSamples = Samples;
00519 ToneToSpkPlayed = 0;
00520 }
00521 }
00522
00523 void rtp::AddToneToAudio(short *buffer, int Samples)
00524 {
00525 if (ToneToSpk != 0)
00526 {
00527 int s = QMIN(Samples, ToneToSpkSamples);
00528 for (int c=0; c<s; c++)
00529 buffer[c] += ToneToSpk[ToneToSpkPlayed+c];
00530 ToneToSpkPlayed += s;
00531 ToneToSpkSamples -= s;
00532 if (ToneToSpkSamples == 0)
00533 {
00534 delete ToneToSpk;
00535 ToneToSpk = 0;
00536 }
00537 }
00538 }
00539
00540
00541 void rtp::Transmit(int ms)
00542 {
00543 rtpMutex.lock();
00544 if (txBuffer)
00545 cerr << "Don't tell me to transmit something whilst I'm already busy\n";
00546 else
00547 {
00548 int Samples = ms * PCM_SAMPLES_PER_MS;
00549 txBuffer = new short[Samples+txPCMSamplesPerPacket];
00550 memset(txBuffer, 0, (Samples+txPCMSamplesPerPacket)*2);
00551 txBufferLen=Samples;
00552 txBufferPtr=0;
00553 txMode = RTP_TX_AUDIO_FROM_BUFFER;
00554 }
00555 rtpMutex.unlock();
00556 }
00557
00558 void rtp::Transmit(short *pcmBuffer, int Samples)
00559 {
00560 if (pcmBuffer && (Samples > 0))
00561 {
00562 rtpMutex.lock();
00563 if (txBuffer)
00564 cerr << "Don't tell me to transmit something whilst I'm already busy\n";
00565 else
00566 {
00567 txBuffer = new short[Samples+txPCMSamplesPerPacket];
00568 memcpy(txBuffer, pcmBuffer, Samples*sizeof(short));
00569 memset(txBuffer+Samples, 0, txPCMSamplesPerPacket*2);
00570 txBufferLen=Samples;
00571 txBufferPtr=0;
00572 txMode = RTP_TX_AUDIO_FROM_BUFFER;
00573 }
00574 rtpMutex.unlock();
00575 }
00576 }
00577
00578 void rtp::Record(short *pcmBuffer, int Samples)
00579 {
00580 rtpMutex.lock();
00581 if (recBuffer)
00582 cerr << "Don't tell me to record something whilst I'm already busy\n";
00583 else
00584 {
00585 recBuffer = pcmBuffer;
00586 recBufferMaxLen=Samples;
00587 recBufferLen=0;
00588 rxMode = RTP_RX_AUDIO_TO_BUFFER;
00589 }
00590 rtpMutex.unlock();
00591 }
00592
00593 void rtp::StreamInAudio()
00594 {
00595 RTPPACKET rtpDump;
00596 RTPPACKET *JBuf;
00597 bool tryAgain;
00598 bool firstFrame = rxFirstFrame;
00599
00600 if (rtpSocket)
00601 {
00602 do
00603 {
00604 tryAgain = false;
00605
00606
00607 if ((JBuf = pJitter->GetJBuffer()) != 0)
00608 {
00609 JBuf->len = rtpSocket->readBlock((char *)&JBuf->RtpVPXCC, sizeof(RTPPACKET));
00610 if (JBuf->len > 0)
00611 {
00612 bytesIn += (JBuf->len + UDP_HEADER_SIZE);
00613 tryAgain = true;
00614 if (PAYLOAD(JBuf) == rtpMPT)
00615 {
00616 pkIn++;
00617 JBuf->RtpSequenceNumber = ntohs(JBuf->RtpSequenceNumber);
00618 JBuf->RtpTimeStamp = ntohl(JBuf->RtpTimeStamp);
00619 if (rxFirstFrame)
00620 {
00621 rxFirstFrame = FALSE;
00622 rxSeqNum = JBuf->RtpSequenceNumber;
00623 peerSsrc = JBuf->RtpSourceID;
00624 }
00625 else
00626 measurePlayoutDelay(JBuf->RtpSequenceNumber);
00627 if (PKLATE(rxSeqNum, JBuf->RtpSequenceNumber))
00628 {
00629 pJitter->FreeJBuffer(JBuf);
00630 pkLate++;
00631 }
00632 else
00633 pJitter->InsertJBuffer(JBuf);
00634 }
00635 else if (PAYLOAD(JBuf) == dtmfPayload)
00636 {
00637 tryAgain = true;
00638 HandleRxDTMF(JBuf);
00639 if (PKLATE(rxSeqNum, JBuf->RtpSequenceNumber))
00640 pJitter->FreeJBuffer(JBuf);
00641 else
00642 pJitter->InsertDTMF(JBuf);
00643 }
00644 else
00645 {
00646 if (PAYLOAD(JBuf) != RTP_PAYLOAD_COMF_NOISE)
00647 cerr << "Received Invalid Payload " << (int)JBuf->RtpMPT << "\n";
00648 else
00649 cout << "Received Comfort Noise Payload\n";
00650 pJitter->FreeJBuffer(JBuf);
00651 }
00652 }
00653 else
00654 pJitter->FreeJBuffer(JBuf);
00655 }
00656
00657
00658
00659 else
00660 {
00661 rtpSocket->readBlock((char *)&rtpDump.RtpVPXCC, sizeof(RTPPACKET));
00662 if (!oobError)
00663 {
00664 cerr << "Dumping received RTP frame, no free buffers; rx-mode " << rxMode << "; tx-mode " << txMode << endl;
00665 pJitter->Debug();
00666 oobError = true;
00667 }
00668 }
00669 } while (tryAgain);
00670
00671
00672
00673 }
00674
00675
00676
00677 if (firstFrame != rxFirstFrame)
00678 {
00679
00680 if (audio)
00681 {
00682 audio->StartSpeaker();
00683 if (audio->samplesOutSpaceRemaining() < PCM_SAMPLES_PER_MS * nominalPlayout)
00684 cout << "RTP error, spk buffer too small for playout delay\n";
00685
00686
00687
00688
00689 int reason;
00690 while (pJitter->count() > 1)
00691 pJitter->FreeJBuffer(pJitter->DequeueJBuffer(rxSeqNum++, reason));
00692 audio->WriteSilence(PCM_SAMPLES_PER_MS * nominalPlayout);
00693 }
00694 }
00695
00696 }
00697
00698 void rtp::PlayOutAudio()
00699 {
00700 bool tryAgain;
00701 int mLen, m, reason, PlayLen;
00702 short decodeBuffer[MAX_DECOMP_AUDIO_SAMPLES];
00703
00704 if (rtpSocket)
00705 {
00706
00707 do
00708 {
00709 tryAgain = false;
00710 RTPPACKET *JBuf = pJitter->DequeueJBuffer(rxSeqNum, reason);
00711 switch (reason)
00712 {
00713 case JB_REASON_OK:
00714 ++rxSeqNum;
00715 mLen = JBuf->len - RTP_HEADER_SIZE;
00716 if (rxMode == RTP_RX_AUDIO_TO_SPEAKER)
00717 {
00718
00719 int playoutAdjust = GetAdjustPlayout();
00720 int playoutOffset = 0;
00721 if (playoutAdjust > 0)
00722 {
00723 audio->WriteSilence(playoutAdjust*PCM_SAMPLES_PER_MS);
00724 bytesToSpeaker += (playoutAdjust*PCM_SAMPLES_PER_MS*sizeof(short));
00725 }
00726 else if (playoutAdjust < 0)
00727 {
00728 playoutOffset = -1 * playoutAdjust*PCM_SAMPLES_PER_MS*sizeof(short);
00729 }
00730
00731 PlayLen = Codec->Decode(JBuf->RtpData, decodeBuffer, mLen, spkPower);
00732 AddToneToAudio(decodeBuffer, PlayLen/sizeof(short));
00733 m = audio->Write(&decodeBuffer[playoutOffset], (PlayLen-playoutOffset)/2);
00734 bytesToSpeaker += m;
00735 }
00736 else if (rxMode == RTP_RX_AUDIO_TO_BUFFER)
00737 {
00738 PlayLen = Codec->Decode(JBuf->RtpData, decodeBuffer, mLen, spkPower);
00739 recordInPacket(decodeBuffer, PlayLen);
00740 if (DTMFFilter)
00741 {
00742 QChar dtmf = DTMFFilter->process(decodeBuffer, PlayLen/sizeof(short));
00743 if (dtmf)
00744 {
00745 rtpMutex.lock();
00746 dtmfIn.append(dtmf);
00747 rtpMutex.unlock();
00748 }
00749 }
00750 }
00751 else
00752 {
00753 if (DTMFFilter)
00754 {
00755 PlayLen = Codec->Decode(JBuf->RtpData, decodeBuffer, mLen, spkPower);
00756 QChar dtmf = DTMFFilter->process(decodeBuffer, PlayLen/sizeof(short));
00757 if (dtmf)
00758 {
00759 rtpMutex.lock();
00760 dtmfIn.append(dtmf);
00761 rtpMutex.unlock();
00762 }
00763 }
00764 }
00765 pJitter->FreeJBuffer(JBuf);
00766 break;
00767
00768 case JB_REASON_DUPLICATE:
00769 if (JBuf != 0)
00770 pJitter->FreeJBuffer(JBuf);
00771 tryAgain = true;
00772 break;
00773
00774 case JB_REASON_DTMF:
00775 ++rxSeqNum;
00776 pJitter->FreeJBuffer(JBuf);
00777 tryAgain = true;
00778 break;
00779
00780 case JB_REASON_EMPTY:
00781 case JB_REASON_MISSING:
00782 rxSeqNum++;
00783 memset(decodeBuffer, 0, rxPCMSamplesPerPacket * sizeof(short));
00784 if (rxMode == RTP_RX_AUDIO_TO_SPEAKER)
00785 {
00786 AddToneToAudio(decodeBuffer, rxPCMSamplesPerPacket);
00787 m = audio->Write(decodeBuffer, rxPCMSamplesPerPacket);
00788 bytesToSpeaker += m;
00789 }
00790 else if (rxMode == RTP_RX_AUDIO_TO_BUFFER)
00791 {
00792 recordInPacket(decodeBuffer, rxPCMSamplesPerPacket * sizeof(short));
00793 }
00794 pkMissed++;
00795 break;
00796
00797 case JB_REASON_SEQERR:
00798 default:
00799
00800 break;
00801 }
00802 } while (tryAgain);
00803 }
00804 }
00805
00806 int rtp::GetAdjustPlayout()
00807 {
00808 int playoutAdjust = 0;
00809
00810
00811 if (adjustPlayoutDelay != 0)
00812 {
00813 rtpMutex.lock();
00814 if (adjustPlayoutDelay > rxMsPacketSize)
00815 {
00816 playoutAdjust = rxMsPacketSize;
00817 adjustPlayoutDelay -= rxMsPacketSize;
00818 nominalPlayout -= rxMsPacketSize;
00819 }
00820 else if (adjustPlayoutDelay < (-1*rxMsPacketSize))
00821 {
00822 playoutAdjust = -1*rxMsPacketSize;
00823 adjustPlayoutDelay += rxMsPacketSize;
00824 nominalPlayout += rxMsPacketSize;
00825 }
00826 else
00827 {
00828 playoutAdjust = adjustPlayoutDelay;
00829 nominalPlayout += adjustPlayoutDelay;
00830 adjustPlayoutDelay = 0;
00831 }
00832 rtpMutex.unlock();
00833 }
00834
00835
00836 else if (avgPlayout != 0)
00837 {
00838 if (avgPlayout > nominalPlayout + 4)
00839 {
00840 avgPlayout = 0;
00841 playoutAdjust = -1;
00842 }
00843 else if (avgPlayout < nominalPlayout - 4)
00844 {
00845 avgPlayout = 0;
00846 playoutAdjust = 1;
00847 }
00848 }
00849
00850 return playoutAdjust;
00851 }
00852
00853 int rtp::measurePlayoutDelay(int seqNum)
00854 {
00855 if (audio == 0)
00856 return 0;
00857
00858
00859
00860 int msDelay=audio->msOutQueued();
00861
00862
00863 int pkCnt = pJitter->countPacketsInFrontOf(seqNum);
00864 msDelay += (pkCnt * rxMsPacketSize);
00865
00866
00867 if ((minPlayout > msDelay) || (minPlayout == -1))
00868 minPlayout = msDelay;
00869 if (maxPlayout < msDelay)
00870 maxPlayout = msDelay;
00871 totPlayout += msDelay;
00872 cntPlayout++;
00873
00874 return msDelay;
00875 }
00876
00877 void rtp::StreamInVideo()
00878 {
00879 RTPPACKET *JBuf;
00880 int mLen, reason;
00881 bool MarketBitSet = false;
00882 bool tryAgain=false;
00883
00884 if (rtpSocket)
00885 {
00886
00887 do
00888 {
00889 tryAgain = false;
00890
00891 if ((JBuf = pJitter->GetJBuffer()) != 0)
00892 {
00893 JBuf->len = rtpSocket->readBlock((char *)&JBuf->RtpVPXCC, sizeof(RTPPACKET));
00894 if (JBuf->len > 0)
00895 {
00896 tryAgain = true;
00897 bytesIn += (JBuf->len + UDP_HEADER_SIZE);
00898 if (PAYLOAD(JBuf) == rtpMPT)
00899 {
00900 if (JBuf->RtpMPT & RTP_PAYLOAD_MARKER_BIT)
00901 {
00902 MarketBitSet = true;
00903 framesIn++;
00904 }
00905 pkIn++;
00906 JBuf->RtpSequenceNumber = ntohs(JBuf->RtpSequenceNumber);
00907 JBuf->RtpTimeStamp = ntohl(JBuf->RtpTimeStamp);
00908 if (rxFirstFrame)
00909 {
00910 rxFirstFrame = FALSE;
00911 videoFrameFirstSeqNum = rxSeqNum = JBuf->RtpSequenceNumber;
00912 peerSsrc = JBuf->RtpSourceID;
00913 }
00914 if (JBuf->RtpSequenceNumber < videoFrameFirstSeqNum)
00915 {
00916 cout << "Packet arrived too late to play, try increasing jitter buffer\n";
00917 pJitter->FreeJBuffer(JBuf);
00918 pkLate++;
00919 }
00920 else
00921 pJitter->InsertJBuffer(JBuf);
00922 }
00923 else
00924 {
00925 cerr << "Received Invalid Payload " << (int)JBuf->RtpMPT << "\n";
00926 pJitter->FreeJBuffer(JBuf);
00927 }
00928 }
00929 else
00930 pJitter->FreeJBuffer(JBuf);
00931 }
00932 else
00933 cerr << "No free buffers, aborting network read\n";
00934 } while (tryAgain);
00935
00936
00937
00938
00939
00940 if (MarketBitSet)
00941 {
00942
00943 int vidLen = pJitter->GotAllBufsInFrame(rxSeqNum, sizeof(H263_RFC2190_HDR));
00944 if (vidLen == 0)
00945 {
00946 ushort valid, missing;
00947 pJitter->CountMissingPackets(rxSeqNum, valid, missing);
00948 cout << "RTP Dropping video frame: Lost Packet\n";
00949 rxSeqNum = pJitter->DumpAllJBuffers(true) + 1;
00950 framesInDiscarded++;
00951 pkMissed += missing;
00952 pkInDisc += valid;
00953 RtcpSendReceive(true);
00954 }
00955 else
00956 {
00957 VIDEOBUFFER *picture = getVideoBuffer(vidLen);
00958 if (picture)
00959 {
00960 int pictureIndex = 0;
00961 bool markerSetOnLastPacket = false;
00962 picture->w = picture->h = 0;
00963
00964
00965 while ((JBuf = pJitter->DequeueJBuffer(rxSeqNum, reason)) != 0)
00966 {
00967 ++rxSeqNum;
00968 mLen = JBuf->len - RTP_HEADER_SIZE - sizeof(H263_RFC2190_HDR);
00969 pictureIndex = appendVideoPacket(picture, pictureIndex, JBuf, mLen);
00970 if (JBuf->RtpMPT & RTP_PAYLOAD_MARKER_BIT)
00971 {
00972 markerSetOnLastPacket = true;
00973 }
00974 if (picture->w == 0)
00975 {
00976 H263_RFC2190_HDR *h263Hdr = (H263_RFC2190_HDR *)JBuf->RtpData;
00977 switch (H263HDR_GETSZ(h263Hdr->h263hdr))
00978 {
00979 case H263_SRC_4CIF: picture->w = 704; picture->h = 576; break;
00980 default:
00981 case H263_SRC_CIF: picture->w = 352; picture->h = 288; break;
00982 case H263_SRC_QCIF: picture->w = 176; picture->h = 144; break;
00983 case H263_SRC_SQCIF: picture->w = 128; picture->h = 96; break;
00984 }
00985 }
00986 pJitter->FreeJBuffer(JBuf);
00987 }
00988
00989
00990 if (pictureIndex > (int)sizeof(picture->video))
00991 {
00992 cout << "SIP: Received video frame size " << pictureIndex << "; too big for buffer\n";
00993 freeVideoBuffer(picture);
00994 framesInDiscarded++;
00995 picture = 0;
00996 }
00997
00998
00999
01000 else if (markerSetOnLastPacket)
01001 {
01002
01003 picture->len = pictureIndex;
01004
01005
01006 rtpMutex.lock();
01007 if (rxedVideoFrames.count() < 3)
01008 {
01009 rxedVideoFrames.append(picture);
01010 rtpMutex.unlock();
01011 }
01012 else
01013 {
01014 rtpMutex.unlock();
01015 freeVideoBuffer(picture);
01016 framesInDiscarded++;
01017 cout << "Discarding frame, app consuming too slowly\n";
01018 }
01019 if (eventWindow)
01020 QApplication::postEvent(eventWindow, new RtpEvent(RtpEvent::RxVideoFrame));
01021 picture = 0;
01022 }
01023 else
01024 {
01025
01026 cout << "RTP Dropping video frame: ";
01027 switch (reason)
01028 {
01029 case JB_REASON_DUPLICATE:
01030 cout << "Duplicate\n";
01031 break;
01032 case JB_REASON_DTMF:
01033 break;
01034 cout << "DTMF\n";
01035 case JB_REASON_MISSING:
01036 cout << "Missed Packets\n";
01037 pkMissed++;
01038 break;
01039 case JB_REASON_EMPTY:
01040 cout << "Empty\n";
01041 break;
01042 case JB_REASON_SEQERR:
01043 cout << "Sequence Error\n";
01044 break;
01045 default:
01046 cout << "Unknown\n";
01047 break;
01048 }
01049 rxSeqNum = pJitter->DumpAllJBuffers(true) + 1;
01050 freeVideoBuffer(picture);
01051 picture = 0;
01052 }
01053 }
01054 else
01055 {
01056 cout << "No buffers for video frame, dropping\n";
01057 rxSeqNum = pJitter->DumpAllJBuffers(true) + 1;
01058 framesInDiscarded++;
01059 }
01060 }
01061 videoFrameFirstSeqNum = rxSeqNum;
01062 }
01063 }
01064 }
01065
01066 int rtp::appendVideoPacket(VIDEOBUFFER *picture, int curLen, RTPPACKET *JBuf, int mLen)
01067 {
01068 if ((curLen + mLen) <= (int)sizeof(picture->video))
01069 {
01070 H263_RFC2190_HDR *h263Hdr = (H263_RFC2190_HDR *)JBuf->RtpData;
01071 int bitOffset = H263HDR_GETSBIT(h263Hdr->h263hdr);
01072 if ((bitOffset == 0) || (curLen == 0))
01073 {
01074 memcpy(&picture->video[curLen], JBuf->RtpData+sizeof(H263_RFC2190_HDR), mLen);
01075 curLen += mLen;
01076 }
01077 else
01078 {
01079 uchar mask = (0xFF >> bitOffset) << bitOffset;
01080 picture->video[curLen-1] &= mask;
01081 picture->video[curLen-1] |= (*(JBuf->RtpData+sizeof(H263_RFC2190_HDR)) & (~mask));
01082 memcpy(&picture->video[curLen], JBuf->RtpData+sizeof(H263_RFC2190_HDR)+1, mLen-1);
01083 curLen += mLen-1;
01084 }
01085 }
01086 return curLen;
01087 }
01088
01089 void rtp::initVideoBuffers(int Num)
01090 {
01091 while (Num-- > 0)
01092 FreeVideoBufferQ.append(new VIDEOBUFFER);
01093 }
01094
01095 VIDEOBUFFER *rtp::getVideoBuffer(int len)
01096 {
01097 if ((len==0) || (len <= MAX_VIDEO_LEN) && (!killRtpThread))
01098 {
01099 VIDEOBUFFER *buf;
01100 rtpMutex.lock();
01101 buf = FreeVideoBufferQ.take(0);
01102 rtpMutex.unlock();
01103 return buf;
01104 }
01105 cerr << "Received video picture size " << len << " too big for preallocated buffer size " << MAX_VIDEO_LEN << endl;
01106 return 0;
01107 }
01108
01109 void rtp::freeVideoBuffer(VIDEOBUFFER *Buf)
01110 {
01111 rtpMutex.lock();
01112 FreeVideoBufferQ.append(Buf);
01113 rtpMutex.unlock();
01114 }
01115
01116 void rtp::destroyVideoBuffers()
01117 {
01118 VIDEOBUFFER *buf = FreeVideoBufferQ.first();
01119 while (buf)
01120 {
01121 FreeVideoBufferQ.remove();
01122 delete buf;
01123 buf = FreeVideoBufferQ.current();
01124 }
01125 }
01126
01127
01128 void rtp::recordInPacket(short *data, int dataBytes)
01129 {
01130 rtpMutex.lock();
01131 if (recBuffer)
01132 {
01133 int bufferLeft = (recBufferMaxLen-recBufferLen)*sizeof(short);
01134 int recBytes = QMIN(dataBytes, bufferLeft);
01135 memcpy(&recBuffer[recBufferLen], data, recBytes);
01136 recBufferLen+=(recBytes/sizeof(short));
01137 if (recBufferLen == recBufferMaxLen)
01138 {
01139
01140 recBuffer = 0;
01141 rxMode = RTP_RX_AUDIO_DISCARD;
01142 }
01143 }
01144 else
01145 rxMode = RTP_RX_AUDIO_DISCARD;
01146 rtpMutex.unlock();
01147 }
01148
01149 void rtp::HandleRxDTMF(RTPPACKET *RTPpacket)
01150 {
01151 DTMF_RFC2833 *dtmf = (DTMF_RFC2833 *)RTPpacket->RtpData;
01152 RTPpacket->RtpSequenceNumber = ntohs(RTPpacket->RtpSequenceNumber);
01153 RTPpacket->RtpTimeStamp = ntohl(RTPpacket->RtpTimeStamp);
01154
01155
01156 if (RTPpacket->RtpTimeStamp != lastDtmfTimestamp)
01157 {
01158 lastDtmfTimestamp = RTPpacket->RtpTimeStamp;
01159 rtpMutex.lock();
01160 dtmfIn.append(DTMF2CHAR(dtmf->dtmfDigit));
01161 cout << "Received DTMF digit " << dtmfIn << endl;
01162 rtpMutex.unlock();
01163 }
01164 }
01165
01166 void rtp::SendWaitingDtmf()
01167 {
01168 if ((dtmfPayload != -1) && (rtpSocket))
01169 {
01170 QChar digit = ' ';
01171 rtpMutex.lock();
01172 if (dtmfOut.length() > 0)
01173 {
01174 digit = dtmfOut[0];
01175 dtmfOut.remove(0,1);
01176 }
01177 rtpMutex.unlock();
01178
01179 if (digit != ' ')
01180 {
01181
01182 RTPPACKET dtmfPacket;
01183 DTMF_RFC2833 *dtmf = (DTMF_RFC2833 *)(dtmfPacket.RtpData);
01184
01185 dtmf->dtmfDigit = CHAR2DTMF(digit);
01186 dtmf->dtmfERVolume = 0x0A;
01187 dtmf->dtmfDuration = htons(0x0500);
01188
01189 txSequenceNumber += 1;
01190 dtmfPacket.RtpVPXCC = 128;
01191 dtmfPacket.RtpMPT = dtmfPayload | RTP_PAYLOAD_MARKER_BIT;
01192 dtmfPacket.RtpSequenceNumber = htons(txSequenceNumber);
01193 dtmfPacket.RtpTimeStamp = htonl(txTimeStamp);
01194 dtmfPacket.RtpSourceID = 0x666;
01195
01196 rtpSocket->writeBlock((char *)&dtmfPacket.RtpVPXCC, RTP_HEADER_SIZE+sizeof(DTMF_RFC2833), yourIP, yourPort);
01197
01198
01199
01200 dtmf->dtmfERVolume = 0x0A | RTP_DTMF_EBIT;
01201 dtmf->dtmfDuration = htons(0x0A00);
01202 dtmfPacket.RtpMPT = dtmfPayload;
01203 rtpSocket->writeBlock((char *)&dtmfPacket.RtpVPXCC, RTP_HEADER_SIZE+sizeof(DTMF_RFC2833), yourIP, yourPort);
01204 }
01205 }
01206 }
01207
01208
01209
01210 void rtp::transmitQueuedVideo()
01211 {
01212
01213
01214 rtpMutex.lock();
01215 VIDEOBUFFER *queuedVideo = videoToTx;
01216 videoToTx = 0;
01217 rtpMutex.unlock();
01218
01219 if (queuedVideo)
01220 {
01221 if ((pTxShaper) && (!pTxShaper->OkToSend()))
01222 {
01223 cout << "Dropped video frame bceause shaper says so\n";
01224 freeVideoBuffer(queuedVideo);
01225 return;
01226 }
01227
01228 framesOut++;
01229
01230 RTPPACKET videoPacket;
01231 uchar *v = queuedVideo->video;
01232 int queuedLen = queuedVideo->len;
01233
01234 txTimeStamp += 25000;
01235
01236 videoPacket.RtpVPXCC = 128;
01237 videoPacket.RtpMPT = videoPayload;
01238 videoPacket.RtpTimeStamp = htonl(txTimeStamp);
01239 videoPacket.RtpSourceID = 0x666;
01240 H263_RFC2190_HDR *h263Hdr = (H263_RFC2190_HDR *)videoPacket.RtpData;
01241 switch (queuedVideo->w)
01242 {
01243 case 704: h263Hdr->h263hdr = H263HDR(H263_SRC_4CIF); break;
01244 default:
01245 case 352: h263Hdr->h263hdr = H263HDR(H263_SRC_CIF); break;
01246 case 176: h263Hdr->h263hdr = H263HDR(H263_SRC_QCIF); break;
01247 case 128: h263Hdr->h263hdr = H263HDR(H263_SRC_SQCIF); break;
01248 }
01249
01250 while (queuedLen > 0)
01251 {
01252 txSequenceNumber += 1;
01253 videoPacket.RtpSequenceNumber = htons(txSequenceNumber);
01254
01255 uint pkLen = queuedLen;
01256 if (pkLen > H263SPACE)
01257 pkLen = H263SPACE;
01258
01259 memcpy(videoPacket.RtpData+sizeof(H263_RFC2190_HDR), v, pkLen);
01260 v += pkLen;
01261 queuedLen -= pkLen;
01262
01263 if (queuedLen == 0)
01264 videoPacket.RtpMPT |= RTP_PAYLOAD_MARKER_BIT;
01265
01266 if (rtpSocket)
01267 {
01268 if (rtpSocket->writeBlock((char *)&videoPacket.RtpVPXCC, RTP_HEADER_SIZE+sizeof(H263_RFC2190_HDR)+pkLen, yourIP, yourPort) == -1)
01269 pkOutDrop++;
01270 else
01271 {
01272 pkOut++;
01273 int sentBytes = (UDP_HEADER_SIZE+RTP_HEADER_SIZE+sizeof(H263_RFC2190_HDR)+pkLen);
01274 bytesOut += sentBytes;
01275 if (pTxShaper)
01276 pTxShaper->Send(sentBytes);
01277 }
01278 }
01279 }
01280
01281 freeVideoBuffer(queuedVideo);
01282 }
01283 }
01284
01285
01286 void rtp::StreamOut(void* pData, int nLen)
01287 {
01288 RTPPACKET RTPpacket;
01289 memcpy(RTPpacket.RtpData, pData, nLen);
01290 RTPpacket.len = nLen;
01291 StreamOut(RTPpacket);
01292 }
01293
01294 void rtp::StreamOut(RTPPACKET &RTPpacket)
01295 {
01296 if (rtpSocket)
01297 {
01298 txSequenceNumber += 1;
01299 txTimeStamp += txPCMSamplesPerPacket;
01300
01301 RTPpacket.RtpVPXCC = 128;
01302 RTPpacket.RtpMPT = rtpMPT | rtpMarker;
01303 rtpMarker = 0;
01304 RTPpacket.RtpSequenceNumber = htons(txSequenceNumber);
01305 RTPpacket.RtpTimeStamp = htonl(txTimeStamp);
01306 RTPpacket.RtpSourceID = 0x666;
01307
01308
01309
01310
01311 if (rtpSocket->writeBlock((char *)&RTPpacket.RtpVPXCC, RTPpacket.len+RTP_HEADER_SIZE, yourIP, yourPort) == -1)
01312 pkOutDrop++;
01313 else
01314 {
01315 bytesOut += (UDP_HEADER_SIZE+RTPpacket.len+RTP_HEADER_SIZE);
01316 pkOut++;
01317 }
01318 }
01319 }
01320
01321
01322 void rtp::fillPacketwithSilence(RTPPACKET &RTPpacket)
01323 {
01324 RTPpacket.len = Codec->Silence(RTPpacket.RtpData, txMsPacketSize);
01325 }
01326
01327 bool rtp::fillPacketfromMic(RTPPACKET &RTPpacket)
01328 {
01329 int gain=0;
01330 short buffer[MAX_DECOMP_AUDIO_SAMPLES];
01331 int len = audio->Read(buffer, MAX_DECOMP_AUDIO_SAMPLES);
01332
01333 if (len != (int)(txPCMSamplesPerPacket*sizeof(short)))
01334 {
01335 fillPacketwithSilence(RTPpacket);
01336 }
01337 else if (micMuted)
01338 fillPacketwithSilence(RTPpacket);
01339 else
01340 RTPpacket.len = Codec->Encode(buffer, RTPpacket.RtpData, txPCMSamplesPerPacket, micPower, gain);
01341
01342 return true;
01343 }
01344
01345 void rtp::fillPacketfromBuffer(RTPPACKET &RTPpacket)
01346 {
01347 rtpMutex.lock();
01348 if (txBuffer == 0)
01349 {
01350 fillPacketwithSilence(RTPpacket);
01351 txMode = RTP_TX_AUDIO_SILENCE;
01352 cerr << "No buffer to playout, changing to playing silence\n";
01353 }
01354 else
01355 {
01356 RTPpacket.len = Codec->Encode(txBuffer+txBufferPtr, RTPpacket.RtpData, txPCMSamplesPerPacket, micPower, 0);
01357 txBufferPtr += txPCMSamplesPerPacket;
01358 if (txBufferPtr >= txBufferLen)
01359 {
01360 delete txBuffer;
01361 txBuffer = 0;
01362 txMode = RTP_TX_AUDIO_SILENCE;
01363 }
01364 }
01365 rtpMutex.unlock();
01366 }
01367
01368 void rtp::RtcpSendReceive(bool forceSend)
01369 {
01370 if (rtcpSocket)
01371 {
01372 int rtcpLen;
01373 RTCPPACKET rtcpPacket;
01374 if ((rtcpLen = rtcpSocket->readBlock((char *)&rtcpPacket, sizeof(RTCPPACKET))) > 0)
01375 {
01376 parseRtcpMessage(&rtcpPacket, rtcpLen);
01377 }
01378
01379
01380
01381
01382 if ((timeNextRtcpTx <= QTime::currentTime()) ||
01383 (forceSend && (timeNextRtcpTx < (QTime::currentTime()).addSecs(RTCP_PERIOD-1))))
01384 {
01385 sendRtcpSenderReport(pkOut, bytesOut, peerSsrc, pkIn, pkMissed, rxSeqNum-1);
01386 timeNextRtcpTx = (QTime::currentTime()).addSecs(RTCP_PERIOD);
01387 }
01388 }
01389 }
01390
01391 void rtp::sendRtcpSenderReport(uint txPkCnt, uint txOctetCnt, long rxSsrc, uint rxPkCnt, uint rxPkLost, ushort highestRxSeq)
01392 {
01393 uint deltaPkLost = rxPkLost - prevRxPkLost;
01394 uint deltaPkRxed = rxPkCnt - prevRxPkCnt;
01395 prevRxPkLost = rxPkLost;
01396 prevRxPkCnt = rxPkCnt;
01397
01398 if (rtcpSocket)
01399 {
01400 RTCPPACKET rtcpPacket;
01401 int len = sizeof(RTCP_SR_BLOCK) + 28;
01402
01403 rtcpPacket.RtcpVPRC = 0x81;
01404 rtcpPacket.RtcpPT = RTCP_SENDER_REPORT;
01405 rtcpPacket.RtcpLen = htons(((sizeof(RTCP_SR_BLOCK) + 28)/4)-1);
01406 rtcpPacket.d.sr.RtcpSsrc = 0x666;
01407 rtcpPacket.d.sr.RtcpNtpTimestampMsw = 0;
01408 rtcpPacket.d.sr.RtcpNtpTimestampLsw = 0;
01409 rtcpPacket.d.sr.RtcpTimestamp = htonl(txTimeStamp);
01410 rtcpPacket.d.sr.RtcpSendPkCount = htonl(txPkCnt);
01411 rtcpPacket.d.sr.RtcpSendOctetCount = htonl(txOctetCnt);
01412
01413 rtcpPacket.d.sr.srBlock[0].Ssrc = rxSsrc;
01414 if ((deltaPkLost+deltaPkRxed) == 0)
01415 rtcpPacket.d.sr.srBlock[0].fractionLost = 0;
01416 else
01417 rtcpPacket.d.sr.srBlock[0].fractionLost = 256*deltaPkLost/(deltaPkLost+deltaPkRxed);
01418
01419 if ((rtcpPacket.d.sr.srBlock[0].fractionLost == 0) && (deltaPkLost > 0))
01420 rtcpPacket.d.sr.srBlock[0].fractionLost = 1;
01421 rtcpPacket.d.sr.srBlock[0].totPacketLostMsb = rxPkLost >> 16;
01422 rtcpPacket.d.sr.srBlock[0].totPacketLostLsw = htons(rxPkLost);
01423 rtcpPacket.d.sr.srBlock[0].extHighestSeqNumRx = htonl(highestRxSeq);
01424 rtcpPacket.d.sr.srBlock[0].arrivalJitter = 0;
01425 rtcpPacket.d.sr.srBlock[0].lastSR = 0;
01426 rtcpPacket.d.sr.srBlock[0].delayLastSR = 0;
01427
01428 rtcpSocket->writeBlock((char *)&rtcpPacket.RtcpVPRC, len, yourIP, yourRtcpPort);
01429 }
01430 }
01431
01432 void rtp::parseRtcpMessage(RTCPPACKET *rtcpPacket, int len)
01433 {
01434 while (len > 0)
01435 {
01436 int chunkLen = (ntohs(rtcpPacket->RtcpLen)+1)*4;
01437 len -= chunkLen;
01438
01439 switch (rtcpPacket->RtcpPT)
01440 {
01441 case RTCP_SENDER_REPORT:
01442 if (ntohl(rtcpPacket->RtcpVPRC & 0x1F) > 0)
01443 {
01444 rtcpFractionLoss = rtcpPacket->d.sr.srBlock[0].fractionLost;
01445 rtcpTotalLoss = ((rtcpPacket->d.sr.srBlock[0].totPacketLostMsb << 16) +
01446 ntohs(rtcpPacket->d.sr.srBlock[0].totPacketLostLsw));
01447 SendRtcpStatistics();
01448 }
01449 break;
01450 case RTCP_RECEIVER_REPORT:
01451 break;
01452 case RTCP_SOURCES_DESCR:
01453 break;
01454 case RTCP_GOODBYE:
01455 break;
01456 case RTCP_APP_DEFINED:
01457 break;
01458 default:
01459 cout << "Received RTCP Unknown Message" << endl;
01460 len = 0;
01461 break;
01462 }
01463
01464 if (len > 0)
01465 rtcpPacket = (RTCPPACKET *)(((uchar *)rtcpPacket) + chunkLen);
01466 }
01467
01468 }
01469
01470
01472
01474
01475 TxShaper::TxShaper(int bw, int period, int granularity)
01476 {
01477 txGranularity = granularity;
01478 historySize = period/granularity;
01479 txHistory = new int[historySize];
01480 for (int cnt=0; cnt<historySize; cnt++)
01481 txHistory[cnt]=0;
01482 txWindowTotal = 0;
01483 maxBandwidth = bw;
01484 itTail = 0;
01485 itHead = 0;
01486
01487 timestamp.start();
01488 timeLastFlush = 0;
01489 timeLastSend = 0;
01490 }
01491
01492 TxShaper::~TxShaper()
01493 {
01494 delete txHistory;
01495 }
01496
01497 bool TxShaper::OkToSend()
01498 {
01499 flushHistory();
01500 return (txWindowTotal < maxBandwidth);
01501 }
01502
01503 void TxShaper::Send(int Bytes)
01504 {
01505 flushHistory();
01506 int timeThisSend = timestamp.elapsed();
01507 itHead += ((timeThisSend - timeLastSend) / txGranularity);
01508 itHead %= historySize;
01509 txHistory[itHead] += Bytes;
01510 txWindowTotal += Bytes;
01511 timeLastSend = timeThisSend;
01512 }
01513
01514 void TxShaper::flushHistory()
01515 {
01516 int timeNow = timestamp.elapsed();
01517 for (int i=timeLastFlush; i<timeNow; i+=txGranularity)
01518 {
01519 txWindowTotal -= txHistory[itTail];
01520 txHistory[itTail++] = 0;
01521 if (itTail>=historySize)
01522 itTail = 0;
01523 }
01524 timeLastFlush = timeNow;
01525 }
01526
01527
01528
01530
01532
01533 Jitter::Jitter():QPtrList<RTPPACKET>()
01534 {
01535
01536 for (int i=0; i<JITTERQ_SIZE; i++)
01537 FreeJitterQ.append(new RTPPACKET);
01538 }
01539
01540
01541 Jitter::~Jitter()
01542 {
01543
01544 RTPPACKET *buf = FreeJitterQ.first();
01545 while (buf)
01546 {
01547 FreeJitterQ.remove();
01548 delete buf;
01549 buf = FreeJitterQ.current();
01550 }
01551
01552
01553 buf = first();
01554 while (buf)
01555 {
01556 remove();
01557 delete buf;
01558 buf = current();
01559 }
01560 }
01561
01562
01563 RTPPACKET *Jitter::GetJBuffer()
01564 {
01565 return (FreeJitterQ.take(0));
01566 }
01567
01568
01569 void Jitter::FreeJBuffer(RTPPACKET *Buf)
01570 {
01571 FreeJitterQ.append(Buf);
01572 }
01573
01574
01575 void Jitter::InsertDTMF(RTPPACKET *Buffer)
01576 {
01577 Buffer->len = 0;
01578 InsertJBuffer(Buffer);
01579 }
01580
01581
01582 void Jitter::InsertJBuffer(RTPPACKET *Buffer)
01583 {
01584 if (count() == 0)
01585 append(Buffer);
01586 else
01587 {
01588
01589 RTPPACKET *latest = getLast();
01590 if (latest->RtpSequenceNumber < Buffer->RtpSequenceNumber)
01591 append(Buffer);
01592
01593
01594 else
01595 {
01596 RTPPACKET *head = first();
01597 cout << "Packet misordering; got " << Buffer->RtpSequenceNumber << ", head " << head->RtpSequenceNumber << ", tail " << latest->RtpSequenceNumber << endl;
01598 inSort(Buffer);
01599 }
01600 }
01601 }
01602
01603
01604 int Jitter::compareItems(QPtrCollection::Item s1, QPtrCollection::Item s2)
01605 {
01606 RTPPACKET *r1 = (RTPPACKET *)s1;
01607 RTPPACKET *r2 = (RTPPACKET *)s2;
01608 return (r1->RtpSequenceNumber - r2->RtpSequenceNumber);
01609 }
01610
01611
01612 RTPPACKET *Jitter::DequeueJBuffer(ushort seqNum, int &reason)
01613 {
01614 RTPPACKET *head = first();
01615
01616
01617 if ((head != 0) && (head->RtpSequenceNumber == seqNum))
01618 {
01619 remove();
01620 reason = JB_REASON_OK;
01621 if (head->len == 0)
01622 reason = JB_REASON_DTMF;
01623 return head;
01624 }
01625
01626
01627 if (head == 0)
01628 reason = JB_REASON_EMPTY;
01629
01630 else if (head->RtpSequenceNumber == seqNum-1)
01631 {
01632 reason = JB_REASON_DUPLICATE;
01633 remove();
01634 }
01635 else if ((head->RtpSequenceNumber < seqNum) || (head->RtpSequenceNumber > seqNum+50))
01636 reason = JB_REASON_SEQERR;
01637 else
01638 reason = JB_REASON_MISSING;
01639
01640 return 0;
01641 }
01642
01643 void Jitter::CountMissingPackets(ushort seq, ushort &cntValid, ushort &cntMissing)
01644 {
01645 RTPPACKET *head = first();
01646 cntValid=0;
01647 cntMissing=0;
01648
01649 while (head != 0)
01650 {
01651 if (head->RtpSequenceNumber == seq)
01652 cntValid++;
01653 else if ((head->RtpSequenceNumber > seq) &&
01654 (head->RtpSequenceNumber < seq+100))
01655 {
01656 cntMissing += (head->RtpSequenceNumber - seq);
01657 }
01658 else
01659 {
01660 cout << "Big gap in RTP sequence numbers, possibly restarted\n";
01661 cntMissing++;
01662 }
01663 seq = head->RtpSequenceNumber + 1;
01664 head = next();
01665 }
01666 }
01667
01668 int Jitter::GotAllBufsInFrame(ushort seq, int offset)
01669 {
01670 RTPPACKET *head = first();
01671 int len=0;
01672
01673 while ((head != 0) && (head->RtpSequenceNumber == seq++))
01674 {
01675 len += (head->len - RTP_HEADER_SIZE - offset);
01676 if (head->RtpMPT & RTP_PAYLOAD_MARKER_BIT)
01677 return len;
01678 head = next();
01679 }
01680 return 0;
01681 }
01682
01683 bool Jitter::isPacketQueued(ushort Seq)
01684 {
01685 RTPPACKET *head = first();
01686
01687
01688 if ((head != 0) && (head->RtpSequenceNumber == Seq))
01689 return true;
01690 return false;
01691 }
01692
01693 int Jitter::countPacketsInFrontOf(ushort Seq)
01694 {
01695 RTPPACKET *head = first();
01696 int cnt=0;
01697
01698 while (head != 0)
01699 {
01700 if (head->RtpSequenceNumber < Seq)
01701 cnt++;
01702 head = next();
01703 }
01704 return cnt;
01705 }
01706
01707 int Jitter::DumpAllJBuffers(bool StopAtMarkerBit)
01708 {
01709 bool MarkerFound = false;
01710 int lastRxSeqNum = 0;
01711
01712 RTPPACKET *head = first();
01713 while ((head) && (!MarkerFound))
01714 {
01715 remove();
01716 lastRxSeqNum = head->RtpSequenceNumber;
01717 if (StopAtMarkerBit && (head->RtpMPT & RTP_PAYLOAD_MARKER_BIT))
01718 MarkerFound = true;
01719 FreeJBuffer(head);
01720 head = current();
01721 }
01722
01723 return lastRxSeqNum;
01724 }
01725
01726 void Jitter::Debug()
01727 {
01728 cout << "Jitter buffers " << count() << " queued " << FreeJitterQ.count() << " free\n";
01729 }
01730
01731
01732
01734
01736
01737 codec::codec()
01738 {
01739 }
01740
01741 codec::~codec()
01742 {
01743 }
01744
01745 int codec::Encode(short *In, uchar *Out, int Samples, short &maxPower, int gain)
01746 {
01747 (void)maxPower;
01748 (void)gain;
01749 memcpy(Out, (char *)In, Samples);
01750 return Samples;
01751 }
01752
01753 int codec::Decode(uchar *In, short *Out, int Len, short &maxPower)
01754 {
01755 (void)maxPower;
01756 memcpy((char *)Out, In, Len);
01757 return Len;
01758 }
01759
01760 int codec::Silence(uchar *out, int ms)
01761 {
01762 int len = ms * PCM_SAMPLES_PER_MS;
01763 memset(out, 0, len);
01764 return len;
01765 }
01766
01767 QString codec::WhoAreYou()
01768 {
01769 return "NO-CODEC";
01770 }
01771
01772