SdpAttributes.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 SdpAttributes_cxx_Version =
  51.     "$Id: SdpAttributes.cxx,v 1.15 2001/06/18 23:52:31 chok Exp $";
  52. #include "support.hxx"
  53. #include "SdpExceptions.hxx"
  54. #include "SdpAttributes.hxx"
  55. /******************** SdpAttributes class methods ***********************/
  56. bool
  57. SdpAttributes::isUserDefined (const char* str)
  58. {
  59.     if (strlen(str) < 2)
  60.         return false;
  61.     if ( (*str == 'X') && (*(str++) == '-') )
  62.         return true;
  63.     else
  64.         return false;
  65. }
  66. /* Parse s and set individual values.
  67.    we are sure we dont get the rtpmap string here, since this is
  68.    called from the Session part, i.e. rtpmap attribute is set
  69.    only within the media attribute 
  70. */
  71. void
  72. SdpAttributes::setAttribute (string& s)
  73. {
  74.     /* the line can be of the form 
  75. a=<attribute>  i.e. Property Attribute OR 
  76. a=<attribute>:<value>  i.e. Value Attribute OR 
  77. a=<userdefined attr>:<value> i.e. User-defined Attribute
  78.     */
  79.     cpLog(LOG_DEBUG_STACK, "SdpAttributes: %s", s.c_str());
  80.     split_t attributeList(split(s, ":"));
  81.     if (attributeList.size() < 1)
  82.     {
  83.         delete(&attributeList);
  84.         cpLog(LOG_ERR, "Attribute: param count < 1 on attributeList");
  85.         throw SdpExceptions(PARAM_NUMERR);
  86.     }
  87.     else if (attributeList.size() == 1) // Property Attribute
  88.     {
  89.         if (attributeList[0] == "recvonly")
  90.         {
  91.             setrecvonly();
  92.         }
  93.         else if (attributeList[0] == "sendrecv")
  94.         {
  95.             setsendrecv();
  96.         }
  97.         else if (attributeList[0] == "sendonly")
  98.         {
  99.             setsendonly();
  100.         }
  101.     }
  102.     else if ( attributeList.size() == 2 ) // Value or User-defined attribute
  103.     {                                       
  104.         cpLog (LOG_DEBUG_STACK, "Attrib, value: %s, %s",
  105.                attributeList[0].c_str(),
  106.                attributeList[1].c_str());
  107.         ValueAttribute* valueAttribute = new ValueAttribute;
  108.         assert (valueAttribute);
  109.         valueAttribute->setAttribute (attributeList[0].c_str());
  110.         valueAttribute->setValue (attributeList[1].c_str());
  111.         addValueAttribute (valueAttribute);
  112.     }
  113.     else if ( attributeList.size() > 2 ) // Assume a value attribute but the value string has : in it
  114.     {
  115.         string value;
  116.         
  117.         value = attributeList[1];
  118.         for (unsigned int i = 2; i <  attributeList.size(); i++)
  119.         {
  120.             value += ":";
  121.             value += attributeList[i];
  122.         }
  123.         cpLog (LOG_DEBUG_STACK, "Attrib, value: %s, %s",
  124.                attributeList[0].c_str(),
  125.                value.c_str());
  126.         ValueAttribute* valueAttribute = new ValueAttribute;
  127.         assert (valueAttribute);
  128.         valueAttribute->setAttribute (attributeList[0].c_str());
  129.         valueAttribute->setValue (value.c_str());
  130.         addValueAttribute (valueAttribute);
  131.     }
  132. }
  133. SdpAttributes::SdpAttributes()
  134.     : recvonly(false),
  135.       sendonly(false),
  136.       sendrecv(false)
  137. {
  138. }
  139. SdpAttributes::SdpAttributes(const SdpAttributes& attr)
  140.     : recvonly(attr.recvonly),
  141.       sendonly(attr.sendonly),
  142.       sendrecv(attr.sendrecv)
  143. {
  144.     //copy user defined attributes from attrib to this.
  145.     //copy individual members.
  146.     copyValueAttributes(attr);
  147. }
  148. void
  149. SdpAttributes::setrecvonly ()
  150. {
  151.     recvonly = true;
  152. }
  153. void
  154. SdpAttributes::setsendrecv ()
  155. {
  156.     sendrecv = true;
  157. }
  158. void
  159. SdpAttributes::setsendonly ()
  160. {
  161.     sendonly = true;
  162. }
  163. bool
  164. SdpAttributes::getrecvonly ()
  165. {
  166.     return recvonly;
  167. }
  168. bool
  169. SdpAttributes::getsendrecv ()
  170. {
  171.     return sendrecv;
  172. }
  173. bool
  174. SdpAttributes::getsendonly ()
  175. {
  176.     return sendonly;
  177. }
  178. void
  179. SdpAttributes::flushValueAttributes ()
  180. {
  181.     vector < ValueAttribute* > ::iterator iter;
  182.     for( iter = valueAttributes.begin(); iter != valueAttributes.end() ; ++iter)
  183.     {
  184.         if (*iter)
  185.         {
  186.             delete (*iter);
  187.         }
  188.     }
  189.     valueAttributes.clear();
  190. }
  191. const SdpAttributes&
  192. SdpAttributes::operator=(SdpAttributes& attrib)
  193. {
  194.     recvonly = attrib.getrecvonly();
  195.     sendonly = attrib.getsendonly();
  196.     sendrecv = attrib.getsendrecv();
  197.     //copy user defined attributes from attrib to this.
  198.     //copy individual members.
  199.     copyValueAttributes(attrib);
  200.     return *(this);
  201. }
  202. void
  203. SdpAttributes::encode (ostrstream& s)
  204. {
  205.     if (recvonly)
  206.     {
  207.         s << "a=" << SdpAttributeRecvonly << "rn";
  208.     }
  209.     else if (sendonly)
  210.     {
  211.         s << "a=" << SdpAttributeSendonly << "rn";
  212.     }
  213.     else if (sendrecv)
  214.     {
  215.         s << "a=" << SdpAttributeSendrecv << "rn";
  216.     }
  217.     vector < ValueAttribute* > ::iterator iter = valueAttributes.begin();
  218.     while (iter != valueAttributes.end())
  219.     {
  220.         (*iter)->encode (s);
  221.         iter++;
  222.     }
  223. }    // SdpAttributes::encode
  224. void
  225. SdpAttributes::copyValueAttributes(const SdpAttributes& attrib)
  226. {
  227.     const vector < ValueAttribute* > * newValueAttributes 
  228. = &attrib.valueAttributes;
  229.     assert(newValueAttributes);
  230.     flushValueAttributes();
  231.     vector < ValueAttribute* > ::const_iterator iter;
  232.     for(iter = newValueAttributes->begin() ;
  233. iter != newValueAttributes->end() ;
  234. ++iter)
  235.     {
  236. if (*iter)
  237. {
  238.     ValueAttribute* valueAttribute = new ValueAttribute;
  239.     assert (valueAttribute);
  240.     //copy the object.
  241.     *valueAttribute = *(*iter);
  242.     //assign to the vector.
  243.     addValueAttribute (valueAttribute);
  244. }
  245. else
  246. {
  247.     addValueAttribute ( 0 );
  248. }
  249.     }
  250. }
  251. /******************** SdpRtpMapAttribute class methods **************************/
  252. SdpRtpMapAttribute::SdpRtpMapAttribute ()
  253. {
  254.     encodingParms = 0;     // no additional audio channel
  255. }
  256. void
  257. SdpRtpMapAttribute::setPayloadType (int payload)
  258. {
  259.     payloadType = payload;
  260. }
  261. int
  262. SdpRtpMapAttribute::getPayloadType ()
  263. {
  264.     return payloadType;
  265. }
  266. void
  267. SdpRtpMapAttribute::setEncodingName (const char* name)
  268. {
  269.     strncpy(encodingName, name, encodingNameLen);
  270.     encodingName[encodingNameLen-1] = '';
  271. }
  272. char*
  273. SdpRtpMapAttribute::getEncodingName ()
  274. {
  275.     return encodingName;
  276. }
  277. void
  278. SdpRtpMapAttribute::setClockRate (int rate)
  279. {
  280.     clockrate = rate;
  281. }
  282. int
  283. SdpRtpMapAttribute::getClockRate ()
  284. {
  285.     return clockrate;
  286. }
  287. void
  288. SdpRtpMapAttribute::setEncodingParms (int parms)
  289. {
  290.     encodingParms = parms;
  291. }
  292. int
  293. SdpRtpMapAttribute::getEncodingParms ()
  294. {
  295.     return encodingParms;
  296. }
  297. ///
  298. void
  299. SdpRtpMapAttribute::encode (ostrstream& s)
  300. {
  301.     cpLog (LOG_DEBUG_STACK, "a=rtpmap:%d %s/%d",
  302.            payloadType,
  303.            encodingName,
  304.            clockrate);
  305.     s << "a=rtpmap:" << payloadType
  306.     << ' '
  307.     << encodingName
  308.     << '/'
  309.     << clockrate;
  310.     if (encodingParms >= 1)    // Number of channels for audio streams
  311.     {                          //   This parameter may be omitted if it is "/1".
  312.                                //   The constructor of this class omits it (set to 0) if it 
  313.                                //     it is not set explicitly.
  314.                                //   If the original line omits it, encodingParms will have
  315.                                //     the default value 0 after decoding.
  316.         cpLog (LOG_DEBUG_STACK, "/%d", encodingParms);
  317.         s << '/' << encodingParms;
  318.     }
  319.     s << "rn";
  320. }    // SdpRtpMapAttribute::encode
  321. /********************** Value Attribute Class Methods *******************/
  322. ValueAttribute::ValueAttribute ()
  323. {
  324. }
  325. char*
  326. ValueAttribute::getAttribute ()
  327. {
  328.     return attribute;
  329. }
  330. void
  331. ValueAttribute::setAttribute (const char* attrib)
  332. {
  333.     strcpy(attribute, attrib);
  334. }
  335. char*
  336. ValueAttribute::getValue ()
  337. {
  338.     return value;
  339. }
  340. void
  341. ValueAttribute::setValue (const char* val)
  342. {
  343.     strcpy(value, val);
  344. }
  345. ///
  346. void
  347. ValueAttribute::encode (ostrstream& s)
  348. {
  349.     s << "a=" << attribute << ':' << value << "rn";
  350. }    // ValueAttribute::encode
  351. /************* Media Attributes class methods ******************/
  352. void
  353. MediaAttributes::setAttribute (string& attrib)
  354. {
  355.     /** check for rtpmap here. The rest is taken care of by the
  356.         parent class : SdpAttributes */
  357.     /* a=rtpmap:...... */
  358.     string::size_type pos;
  359.     pos = attrib.find("rtpmap:");
  360.     if (pos == 0)
  361.     {
  362.         //rtpmap found
  363.         attrib.erase(0, strlen("rtpmap:"));
  364.         split_t attribList(split(attrib, " "));
  365.         if (attribList.size() < 2)
  366.         {
  367.             throw SdpExceptions(PARAM_NUMERR);
  368.         }
  369.         else
  370.         {
  371.             int payload = strtol(attribList[0].c_str(), (char**)NULL, 10);
  372.             SdpRtpMapAttribute* rtpmapAttrib = new SdpRtpMapAttribute;
  373.             assert(rtpmapAttrib);
  374.             rtpmapAttrib->setPayloadType(payload);
  375.             //split the second parameter
  376.             string encodDetails = (attribList[1]);
  377.             split_t encodList(split(encodDetails, "/"));
  378.             rtpmapAttrib->setEncodingName(encodList[0].c_str());
  379.             if (encodList.size() > 1)
  380.             {
  381.                 int rate = strtol(encodList[1].c_str(), (char**)NULL, 10);
  382.                 rtpmapAttrib->setClockRate(rate);
  383.             }
  384.             if (encodList.size() > 2)
  385.             {
  386.                 int encodParms = strtol(encodList[2].c_str(), (char**)NULL, 10);
  387.                 rtpmapAttrib->setEncodingParms(encodParms);
  388.             }
  389.             addmap(rtpmapAttrib);
  390.         }
  391.     }
  392.     else
  393.     {
  394.         cpLog(LOG_DEBUG_STACK, " %s :attribute is not an rtpmap", attrib.c_str());
  395.         //call parent function.
  396.         SdpAttributes::setAttribute(attrib);
  397.     }
  398. }
  399. void
  400. MediaAttributes::flushrtpmap ()
  401. {
  402.     vector < SdpRtpMapAttribute* > ::iterator iter;
  403.     iter = rtpmap.begin();
  404.     while (iter != rtpmap.end())
  405.     {
  406.         if (*iter)
  407.         {
  408.             delete (*iter);
  409.         }
  410.         ++iter;
  411.     }
  412.     rtpmap.clear();
  413. }
  414. MediaAttributes&
  415. MediaAttributes::operator=(MediaAttributes& attrib)
  416. {
  417.     (this)->SdpAttributes::operator=(attrib);
  418.     //copy objects to which rtpmap elements point to
  419.     vector < SdpRtpMapAttribute* > * newrtpmap = attrib.getmap();
  420.     assert(newrtpmap);
  421.     if (newrtpmap->size() > 0)
  422.     {
  423.         cpLog(LOG_DEBUG_STACK, "MediaAttributes: found rtpmap");
  424.         vector < SdpRtpMapAttribute* > ::iterator iter;
  425.         iter = newrtpmap->begin();
  426.         if (rtpmap.size() > 0)
  427.         {
  428.             flushrtpmap();
  429.         }
  430.         while (iter != newrtpmap->end())
  431.         {
  432.             if (*iter)
  433.             {
  434.                 //create an SdpRtpMapAttribute object and put in vector.
  435.                 SdpRtpMapAttribute* thisrtpmap = new SdpRtpMapAttribute();
  436.                 assert(thisrtpmap);
  437.                 *(thisrtpmap) = *(*iter);
  438.                 //assign to the vector.
  439.                 addmap(thisrtpmap);
  440.             }
  441.             ++iter;
  442.         }
  443.     }
  444.     return *(this);
  445. }
  446. ///
  447. void
  448. MediaAttributes::encode (ostrstream& s)
  449. {
  450.     vector < SdpRtpMapAttribute* > ::iterator iter = rtpmap.begin();
  451.     while (iter != rtpmap.end())
  452.     {
  453.         (*iter)->encode (s);
  454.         iter++;
  455.     }
  456.     SdpAttributes::encode (s);
  457. }    // MediaAttributes::encode