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

流媒体/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 SessionData_cxx_Version =
  51.     "$Id: SessionData.cxx,v 1.9 2001/03/23 19:19:08 wjin Exp $";
  52. #include <unistd.h>
  53. #include <sys/types.h>
  54. #include <sys/stat.h>
  55. #include <fcntl.h>
  56. #include <errno.h>
  57. #include "SessionData.hxx"
  58. SessionData::SessionData()
  59.         : stack(0),
  60.         playFileFd( -1),
  61.         recFileFd( -1),
  62.         state(0),
  63.         pktSize(40)
  64. {}
  65. void
  66. SessionData::receivePacket()
  67. {
  68.     RtpPacket* packet = 0;
  69.     if (stack)
  70.     {
  71.         cout << "-";
  72.         packet = stack->receive();
  73.     }
  74.     if (packet)
  75.     {
  76.         if (recFileFd >= 0)
  77.         {
  78.             cout << "x";
  79.             if (packet->getPayloadUsage() != (8 * pktSize))
  80.             {
  81.                 cout << "not the right size!" << endl;
  82.             }
  83.             write (recFileFd,
  84.                    packet->getPayloadLoc(), packet->getPayloadUsage());
  85.         }
  86.         delete packet;
  87.         packet = 0;
  88.     }
  89.     else
  90.     {
  91.         cout << "no packet!" << endl;
  92.     }
  93. }
  94. void
  95. SessionData::transmitPacket()
  96. {
  97.     RtpPacket* packet = 0;
  98.     if (stack)
  99.     {
  100. //        packet = stack->createPacket(pktSize * 8);
  101.         packet = stack->createPacket();
  102.         if (playFileFd >= 0)
  103.         {
  104.             int bytecount =
  105.                 read(playFileFd,
  106.                      packet->getPayloadLoc(), packet->getPayloadSize());
  107.             if (bytecount)
  108.             {
  109.                 packet->setPayloadUsage (bytecount);
  110.                 //      outRtpPkt->setRtpTime(audioStack->getPrevRtpTime() + NETWORK_RTP_RATE);
  111.                 stack->transmit (packet);
  112.             }
  113.             else
  114.             {
  115.                 // this file is now empty -- close and quit
  116.                 close(playFileFd);
  117.                 playFileFd = -1;
  118.                 delete packet;
  119.                 packet = 0;
  120.                 if (state == 1)
  121.                 {
  122.                     // i'm done!
  123.                     state = 2;
  124.                 }
  125.             }
  126.         }
  127.     }
  128. }
  129. void SessionData::newStack(
  130.     const string& localPort,
  131.     const string& remoteHost,
  132.     const string& remotePort )
  133. {
  134.     int localPortNumber = atoi(localPort.c_str());
  135.     int remotePortNumber = atoi(remotePort.c_str());
  136.     if ((localPortNumber < 1024) || (remotePortNumber < 1024))
  137.     {
  138.         return ;
  139.     }
  140.     closeStack();
  141.     stack = new RtpSession(remoteHost.c_str(), remotePortNumber,
  142.                            localPortNumber, remotePortNumber + 1,
  143.                            localPortNumber + 1, rtpPayloadPCMU,
  144.                            rtpPayloadPCMU, 5);
  145.     stack->setApiPktSize (pktSize * 8);
  146.     stack->setNetworkPktSize (pktSize * 8);
  147.     // set SDES information - optional
  148.     RtcpTransmitter* rtcpTran = stack->getRtcpTran();
  149.     rtcpTran->setSdesEmail("development@vovida.com");
  150.     state = 0;
  151. }
  152. void
  153. SessionData::addQueue(const string& str)
  154. {
  155.     queueList.push_back(str);
  156. }
  157. void
  158. SessionData::shouldUseQueue(bool val)
  159. {
  160.     if (val)
  161.     {
  162.         if (state == 0)
  163.         {
  164.             state = 2;
  165.         }
  166.     }
  167.     else
  168.     {
  169.         state = 0;
  170.     }
  171. }
  172. void
  173. SessionData::closeStack()
  174. {
  175.     close(playFileFd);
  176.     close(recFileFd);
  177.     playFileFd = -1;
  178.     recFileFd = -1;
  179.     if (stack)
  180.     {
  181.         stack->transmitRTCPBYE();
  182.         delete stack;
  183.     }
  184.     state = 0;
  185.     stack = 0;
  186. }
  187. void
  188. SessionData::setPktSize(int size)
  189. {
  190.     pktSize = size;
  191. }
  192. void
  193. SessionData::setPlayFile(const string& filename)
  194. {
  195.     cout << "playing file: " << filename << endl;
  196.     if (playFileFd >= 0)
  197.     {
  198.         close(playFileFd);
  199.     }
  200.     // do something about this
  201.     int fd = open(filename.c_str(), O_RDONLY);
  202.     if (fd < 0)
  203.     {
  204.         cout << "error opening file for reading: " << filename << endl;
  205.         cout << "reason: " << strerror(errno) << endl;
  206.         // this is an error
  207.     }
  208.     playFileFd = fd;
  209. }
  210. void SessionData::stopRecord()
  211. {
  212.     // stop recording
  213.     close(recFileFd);
  214.     recFileFd = -1;
  215. }
  216. void SessionData::setRecordFile(const string& filename)
  217. {
  218.     cout << "record file: " << filename << endl;
  219.     if (recFileFd >= 0)
  220.     {
  221.         close(recFileFd);
  222.     }
  223.     // do something about this
  224.     int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
  225.                   S_IRUSR | S_IWUSR);
  226.     if (fd < 0)
  227.     {
  228.         cout << "error opening file for writing!" << endl;
  229.         cout << "reason: " << strerror(errno) << endl;
  230.         // this is an error
  231.     }
  232.     recFileFd = fd;
  233. }
  234. void
  235. SessionData::handleQueue()
  236. {
  237.     // do something about the queue items
  238.     if (state == 2)
  239.     {
  240.         if (queueList.size())
  241.         {
  242.             string cmd = (queueList.front());
  243.             queueList.pop_front();
  244.             state = 1;
  245.             // now, figure out what this means
  246.             if (cmd.length() >= 2)
  247.             {
  248.                 if (cmd[0] == 'p')
  249.                 {
  250.                     // set the play buffer
  251.                     setPlayFile(cmd.substr(2, cmd.length() - 2));
  252.                 }
  253.                 if (cmd[0] == 'r')
  254.                 {
  255.                     // set the record buffer
  256.                     setRecordFile(cmd.substr(2, cmd.length() - 2));
  257.                 }
  258.             }
  259.         }
  260.         else
  261.         {
  262.             // all done!
  263.             state = 0;
  264.         }
  265.     }
  266. }
  267. int SessionData::getFd()
  268. {
  269.     if (stack)
  270.     {
  271.         return stack->getRtpRecv()->getSocketFD();
  272.     }
  273.     else
  274.     {
  275.         return -1;
  276.     }
  277. }
  278. void SessionData::periodicProcess()
  279. {
  280.     VTime currentTime;
  281.     int deltaMs =
  282.         currentTime - lastTimePktSent;
  283.     if (deltaMs > (pktSize - 2))
  284.     {
  285.         // send a packet
  286.         transmitPacket();
  287.         lastTimePktSent = lastTimePktSent + pktSize;
  288.     }
  289.     if (state == 2)
  290.     {
  291.         handleQueue();
  292.     }
  293.     if (stack)
  294.     {
  295.         stack->processRTCP();
  296.     }
  297. }