RtcpReceiver.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:18k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const RtcpReceiver_cxx_Version =
  51.     "$Id: RtcpReceiver.cxx,v 1.9 2001/02/27 00:55:25 larryt Exp $";
  52. #include <iostream>
  53. #include <stdlib.h>
  54. #include <stdio.h>
  55. #include <assert.h>
  56. #include <time.h>
  57. #include <sys/types.h>
  58. #include "vtypes.h"
  59. #include <unistd.h>
  60. #include <string.h>
  61. #include <map>
  62. // networking
  63. #include <sys/types.h>
  64. #include <sys/socket.h>
  65. #include <netinet/in.h>
  66. #include "cpLog.h"
  67. #include "vsock.hxx"
  68. #include "rtpTypes.h"
  69. #include "rtpTools.hxx"
  70. #include "NtpTime.hxx"
  71. #include "Rtp.hxx"
  72. #include "Rtcp.hxx"
  73. /* ----------------------------------------------------------------- */
  74. /* --- rtpcReceiver Constructor ------------------------------------ */
  75. /* ----------------------------------------------------------------- */
  76. RtcpReceiver::RtcpReceiver (int localMinPort, int localMaxPort)
  77. {
  78.     myStack = new UdpStack(NULL, localMinPort, localMaxPort);
  79.     freeStack = true;
  80.     constructRtcpReceiver();
  81. }
  82. RtcpReceiver::RtcpReceiver (int localPort)
  83. {
  84.     myStack = new UdpStack(NULL, localPort) ;
  85.     freeStack = true;
  86.     constructRtcpReceiver();
  87. }
  88. RtcpReceiver::RtcpReceiver (UdpStack* udp)
  89. {
  90.     myStack = udp;
  91.     freeStack = false;
  92.     constructRtcpReceiver();
  93. }
  94. void RtcpReceiver::constructRtcpReceiver ()
  95. {
  96.     packetReceived = 0;
  97.     accumOneWayDelay = 0;
  98.     avgOneWayDelay = 0;
  99.     accumRoundTripDelay = 0;
  100.     avgRoundTripDelay = 0;
  101. }
  102. RtcpReceiver::~RtcpReceiver ()
  103. {
  104.     if (freeStack)
  105.     {
  106.         delete myStack;
  107.         myStack = 0;
  108.     }
  109.     // must remove each transmitter block and each SDES info
  110.     map < RtpSrc, RtpTranInfo* > ::iterator s = tranInfoList.begin();
  111.     while (s != tranInfoList.end())
  112.     {
  113.         removeTranInfo((s->second)->ssrc);
  114.         s = tranInfoList.begin();
  115.     }
  116.     //cpLog(LOG_DEBUG_STACK, "RTCP: Receiver removed");
  117. }
  118. /* --- receive packet functions ------------------------------------ */
  119. RtcpPacket* RtcpReceiver::getPacket ()
  120. {
  121.     // check for network activity
  122.     fd_set netFD;
  123.     FD_ZERO (&netFD);
  124.     FD_SET (myStack->getSocketFD(), &netFD);
  125.     struct timeval timeout;
  126.     timeout.tv_sec = 0;
  127.     timeout.tv_usec = 0;
  128.     int selret = select (myStack->getSocketFD() + 1,
  129.                          &netFD, NULL, NULL, &timeout);
  130.     if (selret <= 0)
  131.     {
  132.         // select error
  133.         if (selret < 0) perror ("rtcpReceiver select");
  134.         else
  135.             // no network activity
  136.             return NULL;
  137.     }
  138.     else
  139.     {
  140.         //cpLog(LOG_DEBUG_STACK, "Get RTCP packet");
  141.     }
  142.     // create packet
  143.     RtcpPacket* p = new RtcpPacket ();
  144.     // receive packet
  145.     //unsigned int fromLen = sizeof (txAddress);
  146.     //int len = recvfrom (socketFD, p->getPacketData(), p->getPacketAlloc(),
  147.     //                    0, (struct sockaddr*) &txAddress, &fromLen);
  148.     //    int len = myStack->receive  (p->getPacketData(), p->getPacketAlloc());
  149.     NetworkAddress sender;
  150.     int len = myStack->receiveFrom (p->getPacketData(),
  151.                                     p->getPacketAlloc(),
  152.                                     &sender);
  153.     //cpLog(LOG_DEBUG_STACK, "RTCP receiveFrom: %s : %d", sender.getIpName().c_str(),
  154.     //          sender.getPort());
  155.     // ? RtpTime arrival = generateTime ();
  156.     if (len <= 0)
  157.     {
  158.         delete p;
  159.         p = NULL;
  160.         return NULL;
  161.     }
  162.     p->setTotalUsage (len);
  163.     // kudo
  164.     //    p->printPacket();
  165.     // check packet
  166.     if (!isValid(p))
  167.     {
  168.         delete p;
  169.         p = NULL;
  170.         return NULL;
  171.     }
  172.     return p;
  173. }
  174. int RtcpReceiver::isValid (RtcpPacket* p)
  175. {
  176.     char* begin = reinterpret_cast < char* > (p->getPacketData());
  177.     char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
  178.     RtcpHeader* middle = reinterpret_cast < RtcpHeader* > (begin);
  179.     // check if known payload type for first packet
  180.     if (middle->type != rtcpTypeSR && middle->type != rtcpTypeRR)
  181.         return 0;
  182.     // check padbyte
  183.     if (middle->padding)
  184.         return 0;
  185.     // check header lengths
  186.     while (begin < end && (int)middle->version == RTP_VERSION)
  187.     {
  188.         begin += (ntohs(middle->length) + 1) * sizeof(RtpSrc);
  189.         middle = reinterpret_cast < RtcpHeader* > (begin);
  190.     }
  191.     if (begin != end)
  192.         return 0;
  193.     // exit with success
  194.     cpLog(LOG_DEBUG_STACK, "RTCP packet is valid");
  195.     //    cout << "RTCP packet is valid" << endl;
  196.     return 1;
  197. }
  198. int RtcpReceiver::readRTCP (RtcpPacket* p)
  199. {
  200.     char* begin = reinterpret_cast < char* > (p->getPacketData());
  201.     char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
  202.     RtcpHeader* middle = NULL;
  203.     int ret = 0;
  204.     while (begin < end)
  205.     {
  206.         middle = reinterpret_cast < RtcpHeader* > (begin);
  207.         switch (middle->type)
  208.         {
  209.             case (rtcpTypeSR):
  210.                         case (rtcpTypeRR):
  211.                             readSR (middle);
  212.             break;
  213.             case (rtcpTypeSDES):
  214.                         readSDES (middle);
  215.             break;
  216.             case (rtcpTypeBYE):
  217.                        if ( readBYE (middle) == 0)
  218.                        {
  219.                            ret = 1;
  220.                        }
  221.             break;
  222.             case (rtcpTypeAPP):
  223.                         readAPP (middle);
  224.             break;
  225.             default:
  226.             cpLog (LOG_ERR, "RTCP: Unknown RTCP type");
  227.             break;
  228.         }
  229.         begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
  230.     }
  231.     return ret;
  232. }
  233. RtcpHeader* RtcpReceiver::findRTCP (RtcpPacket* p, RtcpType type)
  234. {
  235.     char* begin = reinterpret_cast < char* > (p->getPacketData());
  236.     char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
  237.     RtcpHeader* middle = NULL;
  238.     while (begin < end)
  239.     {
  240.         middle = reinterpret_cast < RtcpHeader* > (begin);
  241.         if (type == static_cast < RtcpType > (middle->type))
  242.             return middle;
  243.         begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
  244.     }
  245.     // packet type not found
  246.     cpLog (LOG_ERR, "RTCP: Type found here: %d", (int)type);
  247.     return NULL;
  248. }
  249. /* --- Read SR RTCP packet ----------------------------------------- */
  250. int RtcpReceiver::readSR (RtcpPacket* p)
  251. {
  252.     RtcpHeader* head = findRTCP (p, rtcpTypeSR);
  253.     if (head == NULL) head = findRTCP (p, rtcpTypeRR);
  254.     if (head == NULL) return -1;
  255.     readSR (head);
  256.     // read next RR packet if found
  257.     // future: - ?
  258.     return 0;
  259. }
  260. void RtcpReceiver::readSR (RtcpHeader* head)
  261. {
  262.     char* middle = NULL;
  263.     NtpTime nowNtp = getNtpTime();
  264.     // read SR block
  265.     if (head->type == rtcpTypeSR)
  266.     {
  267.         RtcpSender* senderBlock = reinterpret_cast < RtcpSender* >
  268.                                   ((char*)head + sizeof(RtcpHeader));
  269.         RtpTranInfo* s = findTranInfo(ntohl(senderBlock->ssrc));
  270.         s->lastSRTimestamp = (ntohl(senderBlock->ntpTimeSec) << 16 |
  271.                               ntohl(senderBlock->ntpTimeFrac) >> 16);
  272.         s->recvLastSRTimestamp = nowNtp;
  273.         //printSR (senderBlock);  // - debug
  274.         packetReceived++;
  275.         NtpTime thenNtp ( ntohl(senderBlock->ntpTimeSec),
  276.                           ntohl(senderBlock->ntpTimeFrac) );
  277.         accumOneWayDelay += (nowNtp - thenNtp);
  278.         avgOneWayDelay = accumOneWayDelay / packetReceived;
  279.         middle = (char*)head + sizeof(RtcpHeader) + sizeof(RtcpSender);
  280.     }
  281.     else
  282.     {
  283.         // move over blank SR header
  284.         middle = (char*)head + sizeof(RtcpHeader);
  285.         // move over the ssrc of packet sender
  286.         RtpSrc* sender = reinterpret_cast < RtpSrc* > (middle);
  287.         RtpSrc ssrc;
  288.         ssrc = ntohl(*sender);
  289.         middle += sizeof(RtpSrc);
  290.         packetReceived++;
  291.     }
  292.     // read RR blocks
  293.     RtcpReport* block = reinterpret_cast < RtcpReport* > (middle);
  294.     for (int i = head->count; i > 0; i--)
  295.     {
  296.         //printRR (block);  // - debug
  297.         // - ? what these are if the count is more than 1??
  298.         NtpTime thenNtp (ntohl(block->lastSRTimeStamp) >> 16,
  299.                          ntohl(block->lastSRTimeStamp) << 16 );
  300.         NtpTime nowNtp1 (nowNtp.getSeconds() & 0x0000FFFF, 
  301.                          nowNtp.getFractional() & 0xFFFF0000);
  302.         accumRoundTripDelay += ((nowNtp1 - thenNtp)
  303.                                 - ntohl(block->lastSRDelay));
  304.         avgRoundTripDelay = accumRoundTripDelay / packetReceived;
  305.         ++block;
  306.     }
  307.     // handle profile specific extensions
  308.     // - ?
  309. }
  310. void RtcpReceiver::printSR (RtcpSender* p)
  311. {
  312.     cerr << "Got SR from " << ntohl(p->ssrc) << endl;
  313.     cerr << "  NTP time: " << ntohl(p->ntpTimeSec) << " ";
  314.     cerr << ntohl(p->ntpTimeFrac) << endl;
  315.     cerr << "  RTP time: " << ntohl(p->rtpTime) << endl;
  316.     cerr << "  Packets sent: " << ntohl(p->packetCount);
  317.     cerr << "    Payload sent: " << ntohl(p->octetCount) << endl;
  318. }
  319. void RtcpReceiver::printRR (RtcpReport* p)
  320. {
  321.     cerr << "Got RR for " << ntohl(p->ssrc) << endl;
  322.     cerr << "  Lost Frac: " << p->fracLost;
  323.     u_int32_t lost = (p->cumLost[0] << 16) | (p->cumLost[1] << 8) | p->cumLost[2];
  324.     lost = lost & (0xffffff);
  325.     cerr << "  Lost count: " << lost;
  326.     cerr << "  Cycles: " << ntohs(p->recvCycles);
  327.     cerr << "  Last seq: " << ntohs(p->lastSeqRecv) << endl;
  328.     cerr << "  Jitter: " << ntohl(p->jitter) << "  ";
  329.     cerr << "Last SR: " << ntohl(p->lastSRDelay) << endl;
  330. }
  331. /* --- Read SDES packet -------------------------------------------- */
  332. int RtcpReceiver::readSDES (RtcpPacket* p)
  333. {
  334.     RtcpHeader* head = findRTCP (p, rtcpTypeSDES);
  335.     if (head == NULL) return -1;
  336.     readSDES (head);
  337.     // read next SDES packet if found
  338.     // future: - ?
  339.     return 0;
  340. }
  341. void RtcpReceiver::readSDES (RtcpHeader* head)
  342. {
  343.     char* begin = reinterpret_cast < char* > ((char*)head + sizeof(RtcpHeader));
  344.     RtcpChunk* middle = reinterpret_cast < RtcpChunk* > (begin);
  345.     RtcpSDESItem* item = NULL;
  346.     RtcpSDESItem* nextitem = NULL;
  347.     RtpSrc ssrc;
  348.     for (int i = head->count; i > 0; i--)
  349.     {
  350.         ssrc = ntohl(middle->ssrc);
  351.         for (item = &(middle->startOfItem); item->type; item = nextitem)
  352.         {
  353.             addSDESItem(ssrc, item);
  354.             nextitem = reinterpret_cast < RtcpSDESItem* >
  355.                        ((char*)item + sizeof(RtcpSDESItem) - 1 + item->length);
  356.         }
  357.         middle = reinterpret_cast < RtcpChunk* > (item);
  358.     }
  359. }
  360. void RtcpReceiver::addSDESItem (RtpSrc src, RtcpSDESItem* item)
  361. {
  362.     RtpTranInfo* s = findTranInfo(src);
  363.     switch (item->type)
  364.     {
  365.         case rtcpSdesCname:
  366.         strncpy ((s->SDESInfo).cname, &(item->startOfText), item->length + 1);
  367.         break;
  368.         case rtcpSdesName:
  369.         strncpy ((s->SDESInfo).name, &(item->startOfText), item->length + 1);
  370.         break;
  371.         case rtcpSdesEmail:
  372.         strncpy ((s->SDESInfo).email, &(item->startOfText), item->length + 1);
  373.         break;
  374.         case rtcpSdesPhone:
  375.         strncpy ((s->SDESInfo).phone, &(item->startOfText), item->length + 1);
  376.         break;
  377.         case rtcpSdesLoc:
  378.         strncpy ((s->SDESInfo).loc, &(item->startOfText), item->length + 1);
  379.         break;
  380.         case rtcpSdesTool:
  381.         strncpy ((s->SDESInfo).tool, &(item->startOfText), item->length + 1);
  382.         break;
  383.         case rtcpSdesNote:
  384.         strncpy ((s->SDESInfo).note, &(item->startOfText), item->length + 1);
  385.         break;
  386.         case rtcpSdesPriv:
  387.         // future: not implemented
  388.         default:
  389.         cpLog (LOG_ERR, "RtcpReceiver: SDES type unknown");
  390.         break;
  391.     }
  392.     /*
  393.     // - debug
  394.     cerr <<"Update "<<src<<" with "<< (int) item->type <<" "<< (int) item->length;
  395.     char output [255];
  396.     memset (output, 0, 255);
  397.     strncpy (output, &(item->startOfText), item->length+1);
  398.     cerr << endl <<output<<endl;
  399.     cerr <<"_SDES_";
  400.     */
  401. }
  402. /* --- Read BYE packet --------------------------------------------- */
  403. int RtcpReceiver::readBYE (RtcpPacket* p)
  404. {
  405.     RtcpHeader* head = findRTCP (p, rtcpTypeBYE);
  406.     if (head == NULL) return -1;
  407.     readBYE (head);
  408.     // read next BYE packet if found
  409.     // future: - ?
  410.     return 0;
  411. }
  412. int RtcpReceiver::readBYE (RtcpHeader* head)
  413. {
  414.     //    char* end = reinterpret_cast<char*>
  415.     //                ((char*)head + sizeof(RtpSrc) * (ntohs(head->length) + 1));
  416.     RtpSrc* src = reinterpret_cast < RtpSrc* >
  417.                   ((char*)head + sizeof(RtcpHeader));
  418.     for (int i = head->count; i > 0; i--)
  419.     {
  420.         cpLog( LOG_DEBUG_STACK, "readRtcpBye for %d", ntohl(*src) );
  421.         //       cerr << "readRtcpBye for " << ntohl(*src) << endl;
  422.         removeTranInfo (ntohl(*src++));
  423.     }
  424.     return 0;
  425.     //TODO Convert this to cpLog if necessary
  426. #if 0
  427.     // print reason
  428.     char* middle = reinterpret_cast < char* > (src);
  429.     //    if (middle != end)
  430.     {
  431.         RtcpBye* reason = reinterpret_cast < RtcpBye* > (middle);
  432.         cerr << "   Reason: ";    // - debug
  433.         cerr.write(&(reason->startOfText), (int) reason->length);    // - debug
  434.         cerr << endl;    // - debug
  435.     }
  436.     //cerr <<"_BYE_";  // - debug
  437. #endif
  438. }
  439. /* --- Read APP packet --------------------------------------------- */
  440. int RtcpReceiver::readAPP (RtcpPacket* p)
  441. {
  442.     RtcpHeader* head = findRTCP (p, rtcpTypeAPP);
  443.     if (head == NULL) return -1;
  444.     readAPP (head);
  445.     // read next APP packet if found
  446.     // future: - ?
  447.     return 0;
  448. }
  449. void RtcpReceiver::readAPP (RtcpHeader* head)
  450. {
  451.     // future: not implemented
  452.     assert (0);
  453. }
  454. /* --- known transmitter list functions ---------------------------- */
  455. RtpTranInfo* RtcpReceiver::addTranInfo (RtpSrc src, RtpReceiver* recv)
  456. {
  457.     //    cout << "adding: " << src << endl;
  458.     if (recv) assert (src == recv->ssrc);
  459.     RtpTranInfo* s = new RtpTranInfo;
  460.     s->recv = recv;
  461.     s->ssrc = src;
  462.     s->expectedPrior = 0;
  463.     s->receivedPrior = 0;
  464.     //    cout << "adding ptr: " << s << endl;
  465.     if (addTranFinal (s))
  466.     {
  467.         delete s;  // - ?
  468.         s = findTranInfo (src);
  469.         assert (s->recv == NULL);  // - ?
  470.         s->recv = recv;
  471.     }
  472.     return s;
  473. }
  474. int RtcpReceiver::addTranFinal (RtpTranInfo* s)
  475. {
  476.     // add transmitter to listing
  477.     pair < map < RtpSrc, RtpTranInfo* > ::iterator, bool > result =
  478.         tranInfoList.insert (pair < RtpSrc, RtpTranInfo* >
  479.                              (s->ssrc, s));
  480.     if (!result.second)
  481.     {
  482.         //transmitter already in listing
  483.         return 1;
  484.     }
  485.     //cpLog (LOG_DEBUG_STACK, "RTCP: Transmitter add: %d", s->ssrc);
  486.     return 0;
  487. }
  488. int RtcpReceiver::removeTranInfo (RtpSrc src, int flag)
  489. {
  490.     //    cout << "RTCP: removing: " << src << endl;
  491.     map < RtpSrc, RtpTranInfo* > ::iterator p = tranInfoList.find(src);
  492.     if (p == tranInfoList.end())
  493.     {
  494.         // src not found
  495.         assert (0);
  496.     }
  497.     RtpTranInfo* info = p->second;
  498.     //    cout << "RTCP: removing ptr: " << info << endl;
  499.     // remove from RTP stack
  500.     if (info->recv && !flag)
  501.         (info->recv)->removeSource(info->ssrc, 1);
  502.     info->recv = NULL;
  503.     delete info; info = NULL;
  504.     //    cout << "RTCP: done removingn";
  505.     // remove from receiver list
  506.     tranInfoList.erase (p);
  507.     //cpLog (LOG_DEBUG_STACK, "RTCP: Transmitter removed: %d", src);
  508.     return 0;
  509. }
  510. RtpTranInfo* RtcpReceiver::findTranInfo (RtpSrc src)
  511. {
  512.     RtpTranInfo* info = NULL;
  513.     map < RtpSrc, RtpTranInfo* > ::iterator p = tranInfoList.find(src);
  514.     if (p == tranInfoList.end())
  515.         // receiver not found, so add it
  516.         info = addTranInfo(src);
  517.     else
  518.         info = p->second;
  519.     return info;
  520. }
  521. RtpTranInfo* RtcpReceiver::getTranInfoList (int index)
  522. {
  523.     assert (index >= 0);
  524.     assert (index < getTranInfoCount());
  525.     map < RtpSrc, RtpTranInfo* > ::iterator p = tranInfoList.begin();
  526.     for (int i = 0; i < index; i++)
  527.         ++p;
  528.     assert (p != tranInfoList.end());
  529.     return p->second;
  530. }
  531. int RtcpReceiver::getTranInfoCount()
  532. {
  533.     return tranInfoList.size();
  534. }
  535. int RtcpReceiver::getPort ()
  536. {
  537.     return myStack->getRxPort();
  538. };
  539. int RtcpReceiver::getSocketFD ()
  540. {
  541.     return myStack->getSocketFD();
  542. };