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

流媒体/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 RtpTransmitter_cxx_Version =
  51.     "$Id: RtpTransmitter.cxx,v 1.14 2001/05/07 19:12:50 kle 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. // network socket
  62. //#include <netinet/in.h>                // struct socketaddr_in
  63. //#include <sys/socket.h>
  64. //#include <netdb.h>
  65. #include "cpLog.h"
  66. #include "vsock.hxx"
  67. #include "NetworkAddress.h"
  68. #include "NtpTime.hxx"
  69. #include "rtpTypes.h"
  70. #include "rtpTools.hxx"
  71. #include "Rtp.hxx"
  72. #include "rtpCodec.h"
  73. /* ----------------------------------------------------------------- */
  74. /* --- RtpTransmitter Constructor ---------------------------------- */
  75. /* ----------------------------------------------------------------- */
  76. RtpTransmitter::RtpTransmitter (const char* remoteHost,
  77.                                 int remoteMinPort, int remoteMaxPort,
  78.                                 RtpPayloadType newApiFormat,
  79.                                 RtpPayloadType newNetworkFormat,
  80.                                 RtpReceiver* receiver)
  81. {
  82.     NetworkAddress netAddress;
  83.     if(  remoteHost )
  84.     {
  85.         netAddress.setHostName(remoteHost);
  86.         netAddress.setPort(remoteMinPort);
  87.     }
  88.     if(  receiver )
  89.     {
  90.         myStack = receiver->getUdpStack();
  91.         myStack->setDestination(&netAddress);
  92.         remoteAddr = netAddress;
  93.         // assume that RTP will always use send instead of sendto
  94.         // so that it can only receive from/send to the same remote port
  95.         // myStack->connectPorts();
  96.         freeStack = false;
  97.     }
  98.     else
  99.     {
  100.         myStack = new UdpStack (&netAddress, remoteMinPort,
  101.                                 remoteMaxPort, sendonly) ;
  102.         remoteAddr = netAddress;
  103.         // myStack->connectPorts();
  104.         freeStack = true;
  105.     }
  106.     constructRtpTransmitter (newApiFormat, newNetworkFormat);
  107. }
  108. RtpTransmitter::RtpTransmitter (const char* remoteHost, int remotePort,
  109.                                 RtpPayloadType newApiFormat,
  110.                                 RtpPayloadType newNetworkFormat,
  111.                                 RtpReceiver* receiver)
  112. {
  113.     NetworkAddress netAddress;
  114.     if(  remoteHost )
  115.     {
  116.         netAddress.setHostName(remoteHost);
  117.         netAddress.setPort(remotePort);
  118.     }
  119.     if(  receiver )
  120.     {
  121.         myStack = receiver->getUdpStack();
  122.         myStack->setDestination(&netAddress);
  123.         remoteAddr = netAddress;
  124.         // myStack->connectPorts();
  125.         freeStack = false;
  126.     }
  127.     else
  128.     {
  129.         myStack = new UdpStack (&netAddress, remotePort,
  130.                                 remotePort, sendonly) ;
  131.         remoteAddr = netAddress;
  132.         // myStack->connectPorts();
  133.         freeStack = true;
  134.     }
  135.     constructRtpTransmitter (newApiFormat, newNetworkFormat);
  136. }
  137. void RtpTransmitter::constructRtpTransmitter (RtpPayloadType newApiFormat,
  138.         RtpPayloadType newNetworkFormat)
  139. {
  140.     outPos = 0;
  141.     recPos = 0;
  142.     memset (outBuff, 0, OUT_BUFFER_SIZE);
  143.     // set format and baseSampleRate
  144.     setApiFormat(newApiFormat, 160, 0, NULL, false);
  145.     setNetworkFormat(newNetworkFormat, 160, 0, NULL, false);
  146.     // set private variables
  147.     ssrc = generateSRC();
  148.     seedNtpTime = getNtpTime();
  149.     seedRtpTime = generate32();
  150.     prevNtpTime = seedNtpTime;
  151.     prevRtpTime = seedRtpTime;
  152.     prevSequence = generate32();
  153.     // set counters
  154.     packetSent = 0;
  155.     payloadSent = 0;
  156.     cpLog(LOG_DEBUG_STACK, "Constructed ssrc = %d", ssrc);
  157. }
  158. RtpTransmitter::~RtpTransmitter ()
  159. {
  160.     if( freeStack)
  161.     {
  162.         delete myStack;
  163.         myStack = NULL;
  164.     }
  165.     cpLog(LOG_DEBUG_STACK, "Closed ssrc = %d", ssrc);
  166. }
  167. void
  168. RtpTransmitter::setRemoteAddr (const NetworkAddress& theAddr)
  169. {
  170.     remoteAddr = theAddr;
  171. }
  172. /* --- send packet functions --------------------------------------- */
  173. RtpPacket* RtpTransmitter::createPacket (int npadSize, int csrc_count)
  174. {
  175.     // create packet
  176.     RtpPacket* packet = new RtpPacket (apiFormat_payloadSize, npadSize, csrc_count);
  177.     assert (packet);
  178.     // load packet
  179.     packet->setSSRC (ssrc);
  180.     packet->setPayloadType (apiFormat);
  181.     return packet;
  182. }
  183. // takes api RTP packet and send to network
  184. // assumes payload size is already set
  185. int RtpTransmitter::transmit(RtpPacket* packet, bool eventFlag )
  186. {
  187.     if( !packet )
  188.     {
  189.         cpLog(LOG_ERR,"Attempting to transmit a NULL rtp packet");
  190.         return -1;
  191.     }
  192.     RtpPacket* p = packet;
  193.     // convert codec
  194.     if( p->getPayloadType() != networkFormat  &&  !eventFlag )
  195.     {
  196. #ifndef __sparc
  197.         // replace p with a new packet
  198.         p = convertRtpPacketCodec (networkFormat, packet);
  199.         assert (packet->getSequence() == p->getSequence());
  200. #endif
  201.     }
  202.     rtp_htonl(p);
  203.     // finish packet
  204.     if( p->getPayloadUsage() != networkFormat_payloadSize  &&  !eventFlag )
  205.     {
  206.         cpLog(LOG_DEBUG_STACK,"Sending mismatched packetSize(%d) to networkFormatSize(%d)",
  207.               p->getPayloadUsage(), networkFormat_payloadSize);
  208.     }
  209.     if( !p->timestampSet )
  210.         p->setRtpTime( prevRtpTime + network_pktSampleSize );
  211.     if( !p->sequenceSet )
  212.         p->setSequence( prevSequence + 1 );
  213.     if( p->getPayloadUsage() < 0  ||  p->getPayloadUsage() > 1012 )
  214.     {
  215.         cpLog(LOG_DEBUG_STACK,"Invalid data packet size %d", p->getPayloadUsage());
  216.         return -1;
  217.     }
  218.     //set marker once
  219.     if( markerOnce )
  220.     {
  221.         cpLog( LOG_DEBUG_STACK,"Setting marker bit once");
  222.         p->setMarkerFlag(1);
  223.         markerOnce = false;
  224.     }
  225.     // for packet reuse
  226.     p->timestampSet = false;
  227.     p->sequenceSet = false;
  228.     // transmit packet
  229.     try
  230.     {
  231.         myStack->transmitTo( (char*)p->getHeader(), p->getTotalUsage(), &remoteAddr );
  232.     }
  233.     catch( UdpStackExceptionConectionRefused& e )
  234.     {
  235.         cpLog (LOG_ERR,"Connection refused");
  236.         return -1;
  237.     }
  238.     // update counters
  239.     packetSent++;
  240.     prevSequence = p->getSequence();
  241.     if( !eventFlag )
  242.     {
  243.         payloadSent += p->getPayloadUsage();
  244.         prevNtpTime = getNtpTime();
  245.         prevRtpTime = p->getRtpTime();
  246.     }
  247.     // set up return value
  248.     int result = p->getPayloadUsage();
  249.     // delete newly created packet
  250.     if( ( p != packet )  &&  p )
  251.     {
  252.         delete p; p = NULL;
  253.     }
  254.     // exit with success
  255.     return result;
  256. }
  257. // takes rawdata, buffers it, and send network packets
  258. int RtpTransmitter::transmitRaw (char* data, int len)
  259. {
  260.     int len1;
  261.     // convert codec
  262.     if( apiFormat != networkFormat)
  263.     {
  264.         char* buffer = new char[1012];
  265.         len = convertCodec(apiFormat, networkFormat, data, buffer, len);
  266.         data = buffer;
  267.     }
  268.     // write packet to output buffer
  269.     if( (outPos + len) < OUT_BUFFER_SIZE)
  270.     {
  271.         memcpy (outBuff + outPos, data, len);
  272.         outPos += len;
  273.     }
  274.     else
  275.     {
  276.         // circular memory copy
  277.         len1 = OUT_BUFFER_SIZE - outPos;
  278.         memcpy (outBuff + outPos, data, len1);
  279.         memcpy (outBuff, data + len1, len - len1);
  280.         outPos = len - len1;
  281.     }
  282.     // check if enough data to send out packet
  283.     int packetSize = networkFormat_payloadSize;
  284.     if(  (outPos == 0) && (recPos == 0) )
  285.     {
  286.         cpLog (LOG_DEBUG_STACK, "Buffer is empty");
  287.         return 0;
  288.     }
  289.     if(  ((outPos + OUT_BUFFER_SIZE - recPos) % OUT_BUFFER_SIZE) < packetSize )
  290.     {
  291.         cpLog (LOG_DEBUG_STACK, "Not enough data for a network packet.  Need %d",
  292.                packetSize);
  293.         return 0;
  294.     }
  295.     // send out packets from buffer
  296.     int result = 0;
  297.     // create packet
  298.     RtpPacket* p = new RtpPacket (networkFormat_payloadSize);
  299.     assert (p);
  300.     p->setSSRC (ssrc);
  301.     p->setPayloadType (networkFormat);
  302.     p->setPayloadUsage (packetSize);
  303.     //fill packets
  304.     while ( ((outPos + OUT_BUFFER_SIZE - recPos) % OUT_BUFFER_SIZE) >= packetSize )
  305.     {
  306.         if(  (recPos + packetSize) < OUT_BUFFER_SIZE)
  307.         {
  308.             memcpy (p->getPayloadLoc(), outBuff + recPos, packetSize);
  309.             recPos += packetSize;
  310.         }
  311.         else
  312.         {
  313.             // circular memory write
  314.             len1 = OUT_BUFFER_SIZE - recPos;
  315.             memcpy (p->getPayloadLoc(), outBuff + recPos, len1);
  316.             memcpy (p->getPayloadLoc() + len1, outBuff, packetSize - len1);
  317.             recPos = packetSize - len1;
  318.         }
  319.         // finish packet
  320.         result += transmit(p);
  321.     }
  322.     if( p) delete p;
  323.     p = NULL;
  324.     // exit with success
  325.     return result;
  326. }
  327. void RtpTransmitter::setNetworkFormat (RtpPayloadType newtype, int no_samples, int packetSize,
  328.                                        RtpPacket* p, bool print)
  329. {
  330.     networkFormat = newtype;
  331.     network_pktSampleSize = no_samples;
  332.     networkFormat_perSampleSize = 1;
  333.     switch (newtype)
  334.     {
  335.         case rtpPayloadPCMU:
  336.         case rtpPayloadPCMA:
  337.         if( print) cpLog(LOG_DEBUG, "Setting network format to: PCMU %d", no_samples);
  338.         networkFormat_clockRate = 8000;
  339.         break;
  340.         case rtpPayloadL16_mono:
  341.         if( print) cpLog(LOG_DEBUG, "Setting network format to: L16 %d", no_samples);
  342.         networkFormat_clockRate = 44100;
  343.         networkFormat_perSampleSize = 2;
  344.         break;
  345.         case rtpPayloadG729:
  346.         if( print) cpLog(LOG_DEBUG, "Setting network format to: G729 %d", no_samples);
  347.         networkFormat_clockRate = 8000;
  348.         break;
  349.         default:
  350.         cpLog(LOG_ERR, "Unknown networkFormat: codec(%d) samples(%d) packetSize(%d)",
  351.               (int)networkFormat, no_samples, packetSize);
  352.         networkFormat_clockRate = 8000;
  353.     }
  354.     if( p )
  355.         networkFormat_payloadSize = p->getPayloadUsage();
  356.     else
  357.         networkFormat_payloadSize = network_pktSampleSize * networkFormat_perSampleSize;
  358.     if( packetSize != 0 )
  359.         networkFormat_payloadSize = packetSize;
  360. }
  361. void RtpTransmitter::setApiFormat (RtpPayloadType newtype, int no_samples, int packetSize,
  362.                                    RtpPacket* p, bool print)
  363. {
  364.     apiFormat = newtype;
  365.     api_pktSampleSize = no_samples;
  366.     apiFormat_perSampleSize = 1;
  367.     switch( newtype )
  368.     {
  369.     case rtpPayloadPCMU:
  370.     case rtpPayloadPCMA:
  371.         if( print ) cpLog(LOG_DEBUG, "Setting api format to: PCMU %d", no_samples);
  372.         apiFormat_clockRate = 8000;
  373.         break;
  374.     case rtpPayloadL16_mono:
  375.         if( print ) cpLog(LOG_DEBUG, "Setting api format to: L16 %d", no_samples);
  376.         apiFormat_clockRate = 44100;
  377.         apiFormat_perSampleSize = 2;
  378.         break;
  379.     case rtpPayloadG729:
  380.         if( print ) cpLog(LOG_DEBUG, "Setting api format to: G729 %d", no_samples);
  381.         apiFormat_clockRate = 8000;
  382.         break;
  383.     default:
  384.         cpLog(LOG_ERR, "Unknown apiFormat: codec(%d) samples(%d) packetSize(%d)",
  385.               (int)apiFormat, no_samples, packetSize);
  386.         apiFormat_clockRate = 8000;
  387.     }
  388.     if( p )
  389.         apiFormat_payloadSize = p->getPayloadUsage();
  390.     else
  391.         apiFormat_payloadSize = api_pktSampleSize * apiFormat_perSampleSize;
  392.     if( packetSize != 0 )
  393.         apiFormat_payloadSize = packetSize;
  394. }