Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 7c0c66d6521a2c8efa0ef6bf03291d7f > files > 332

jrtplib-devel-3.7.1-7.fc12.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>jrtplib: JRTPLIB</title>
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="jrtplib.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.9 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li class="current"><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
      <li><a href="dirs.html"><span>Directories</span></a></li>
    </ul>
  </div>
</div>
<div class="contents">
<h1>JRTPLIB</h1>
<p>
<h3 align="center">3.7.1 </h3><dl class="author" compact><dt><b>Author:</b></dt><dd>Jori Liesenborgs <p>
Developed at the The Expertise Centre for Digital Media (EDM), a research institute of the Hasselt University</dd></dl>
<h2><a class="anchor" name="ack">
Acknowledgment</a></h2>
I would like thank the people at the Expertise Centre for Digital Media for giving me the opportunity to create this rewrite of the library.<h2><a class="anchor" name="intro">
Introduction</a></h2>
This document describes JRTPLIB, an object-oriented library written in C++ which aims to help developers in using the Real-time Transport Protocol (RTP) as described in RFC 3550.<p>
The library makes it possible for the user to send and receive data using RTP, without worrying about SSRC collisions, scheduling and transmitting RTCP data etc. The user only needs to provide the library with the payload data to be sent and the library gives the user access to incoming RTP and RTCP data.<h3><a class="anchor" name="idea">
Design idea</a></h3>
The library provides several classes which can be helpful in creating RTP applications. Most users will probably need just the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class for building an application. This class provides the necessary functions for sending RTP data and handles the RTCP part internally.<h3><a class="anchor" name="changes">
Changes from version 2.x</a></h3>
One of the most important changes is probably the fact that this version is based on RFC 3550 and the 2.x versions were based upon RFC 1889 which is now obsolete.<p>
Also, the 2.x series was created with the idea that the user would only need to use the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class which meant that the other classes were not very useful by themselves. This version on the other hand, aims to provide many useful components to aid the user in building RTP capable applications.<p>
In this version, the code which is specific for the underlying protocol by which RTP packets are transported, is bundled in a class which inherits its interface from a class called <a class="el" href="classRTPTransmitter.html" title="Abstract class from which actual transmission components should be derived.">RTPTransmitter</a>. This makes it easy for different underlying protocols to be supported. Currently there is support for UDP over IPv4 and UDP over IPv6.<p>
For applications such as a mixer or translator using the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class will not be a good solution. Other components can be used for this purpose: a transmission component, an SSRC table, an RTCP scheduler etc. Using these, it should be much easier to build all kinds of applications. <h2><a class="anchor" name="copyright">
Copyright license</a></h2>
The library code uses the following copyright license:<p>
<div class="fragment"><pre class="fragment"> Permission is hereby granted, free of charge, to any person
 obtaining a copy of <span class="keyword">this</span> software and associated documentation files
 (the <span class="stringliteral">"Software"</span>), to deal in the Software without restriction,
 including without limitation the rights to use, copy, modify, merge,
 publish, distribute, sublicense, and/or sell copies of the Software,
 and to permit persons to whom the Software is furnished to <span class="keywordflow">do</span> so,
 subject to the following conditions:

 The above copyright notice and <span class="keyword">this</span> permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED <span class="stringliteral">"AS IS"</span>, WITHOUT WARRANTY OF ANY
 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
</pre></div><p>
There are two reasons for using this license. First, since this is the license of the 2.x series, it only seemed natural that this rewrite would contain the same license. Second, since the RTP protocol is deliberately incomplete RTP profiles can, for example, define additional header fields. The best way to deal with this is to adapt the library code itself and that's why I like to keep the license as free as possible.<h2><a class="anchor" name="starting">
Getting started with the RTPSession class</a></h2>
To use RTP, you'll have to create an <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> object. The constructor accepts one parameter, an instance of <a class="el" href="classRTPMemoryManager.html" title="A memory manager.">RTPMemoryManager</a>. By default, no memory manager will be used. For now, we'll keep it simple, so this is our code so far:<p>
<div class="fragment"><pre class="fragment"> <a class="code" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> session; 
</pre></div><p>
To actually create the session, you'll have to call the Create member function which takes three arguments: the first one is of type <a class="el" href="classRTPSessionParams.html" title="Describes the parameters for to be used by an RTPSession instance.">RTPSessionParams</a> and specifies the general options for the session. One parameter of this class must be set explicitly, otherwise the session will not be created successfully. This parameter is the timestamp unit of the data you intend to send and can be calculated by dividing a certain time interval (in seconds) by the number of samples in that interval. So, assuming that we'll send 8000 Hz voice data, we can use this code:<p>
<div class="fragment"><pre class="fragment"> <a class="code" href="classRTPSessionParams.html" title="Describes the parameters for to be used by an RTPSession instance.">RTPSessionParams</a> sessionparams;

 sessionparams.<a class="code" href="classRTPSessionParams.html#7edf8de28827890508192680a733a8a0" title="Sets the timestamp unit for our own data.">SetOwnTimestampUnit</a>(1.0/8000.0);
</pre></div><p>
The other session parameters will probably depend on the actual RTP profile you intend to work with.<p>
The second argument of the Create function is a pointer to an <a class="el" href="classRTPTransmissionParams.html" title="Base class for transmission parameters.">RTPTransmissionParams</a> instance and describes the parameters for the transmission component. The third parameter selects the type of transmission component which will be used. By default, an UDP over IPv4 transmitter is used, and for this particular transmitter, the transmission parameters should be of type <a class="el" href="classRTPUDPv4TransmissionParams.html" title="Parameters for the UDP over IPv4 transmitter.">RTPUDPv4TransmissionParams</a>. Assuming that we want our RTP portbase to be 8000, we can do the following:<p>
<div class="fragment"><pre class="fragment"> <a class="code" href="classRTPUDPv4TransmissionParams.html" title="Parameters for the UDP over IPv4 transmitter.">RTPUDPv4TransmissionParams</a> transparams;
 
 transparams.<a class="code" href="classRTPUDPv4TransmissionParams.html#a8f9e29f0a0380a3b0334d873b558895" title="Sets the RTP portbase to pbase.">SetPortbase</a>(8000);
</pre></div><p>
Now, we're ready to call the Create member function of <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a>. The return value is stored in the integer <code>status</code> so we can check if something went wrong. If this value is negative, it indicates that some error occurred. A description of what this error code means can be retrieved by calling RTPGetErrorString:<p>
<div class="fragment"><pre class="fragment"> <span class="keywordtype">int</span> status = session.<a class="code" href="classRTPSession.html#34bc0beffb09c81b94f39758dfd13826" title="Creates an RTP session.">Create</a>(sessionparams,&amp;transparams);
 <span class="keywordflow">if</span> (status &lt; 0)
 {
        std::cerr &lt;&lt; <a class="code" href="rtperrors_8h.html#e80376110962d8f7745bba2116c209dc" title="Returns a string describing the error code errcode.">RTPGetErrorString</a>(status) &lt;&lt; std::endl;
        exit(-1);
 }
</pre></div><p>
If the session was created with success, this is probably a good point to specify to which destinations RTP and RTCP data should be sent. This is done by a call to the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> member function AddDestination. This function takes an argument of type <a class="el" href="classRTPAddress.html" title="This class is an abstract class which is used to specify destinations, multicast...">RTPAddress</a>. This is an abstract class and for the UDP over IPv4 transmitter the actual class to be used is <a class="el" href="classRTPIPv4Address.html" title="Represents an IPv4 IP address and port.">RTPIPv4Address</a>. Suppose that we want to send our data to a process running on the same host at port 9000, we can do the following:<p>
<div class="fragment"><pre class="fragment"> uint8_t localip[]={127,0,0,1};
 <a class="code" href="classRTPIPv4Address.html" title="Represents an IPv4 IP address and port.">RTPIPv4Address</a> addr(localip,9000);

 status = session.<a class="code" href="classRTPSession.html#11ebaa614e8b8500d8de4fe64885d36d" title="Adds addr to the list of destinations.">AddDestination</a>(addr);
 <span class="keywordflow">if</span> (status &lt; 0)
 {
        std::cerr &lt;&lt; <a class="code" href="rtperrors_8h.html#e80376110962d8f7745bba2116c209dc" title="Returns a string describing the error code errcode.">RTPGetErrorString</a>(status) &lt;&lt; std::endl;
        exit(-1);
 }
</pre></div><p>
If the library was compiled with JThread support, incoming data is processed in the background. If JThread support was not enabled at compile time or if you specified in the session parameters that no poll thread should be used, you'll have to call the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> member function Poll regularly to process incoming data and to send RTCP data when necessary. For now, let's assume that we're working with the poll thread enabled.<p>
Lets suppose that for a duration of one minute, we want to send packets containing 20 ms (or 160 samples) of silence and we want to indicate when a packet from someone else has been received. Also suppose we have L8 data as defined in RFC 3551 and want to use payload type 96. First, we'll set some default values:<p>
<div class="fragment"><pre class="fragment"> session.<a class="code" href="classRTPSession.html#79ff535fbd4031d81ec28ad05b1b5439" title="Sets the default payload type for RTP packets to pt.">SetDefaultPayloadType</a>(96);
 session.<a class="code" href="classRTPSession.html#37172f082df1a452c2e9d3b86d5dc773" title="Sets the default marker for RTP packets to m.">SetDefaultMark</a>(<span class="keyword">false</span>);
 session.<a class="code" href="classRTPSession.html#97f5a1eef424452e4975aec7bd9f112d" title="Sets the default value to increment the timestamp with to timestampinc.">SetDefaultTimestampIncrement</a>(160);
</pre></div><p>
Next, we'll create the buffer which contains 160 silence samples and create an <a class="el" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a> instance which indicates 20 ms or 0.020 seconds. We'll also store the current time so we'll know when one minute has passed.<p>
<div class="fragment"><pre class="fragment"> uint8_t silencebuffer[160];
 
 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0 ; i &lt; 160 ; i++)
        silencebuffer[i] = 128;
 
 <a class="code" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a> delay(0.020);
 <a class="code" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a> starttime = <a class="code" href="classRTPTime.html#de5ba279f814edb9894ced694845fdad" title="Returns an RTPTime instance representing the current wallclock time.">RTPTime::CurrentTime</a>();
</pre></div><p>
Next, the main loop will be shown. In this loop, a packet containing 160 bytes of payload data will be sent. Then, data handling can take place but this part is described later in the text. Finally, we'll wait 20 ms and check if sixty seconds have passed:<p>
<div class="fragment"><pre class="fragment"> <span class="keywordtype">bool</span> done = <span class="keyword">false</span>;
 <span class="keywordflow">while</span> (!done)
 {
        status = session.<a class="code" href="classRTPSession.html#a9095e0c8bd08a5a46c42feac4ea079f" title="Sends the RTP packet with payload data which has length len.">SendPacket</a>(silencebuffer,160);
        <span class="keywordflow">if</span> (status &lt; 0)
        {
                std::cerr &lt;&lt; <a class="code" href="rtperrors_8h.html#e80376110962d8f7745bba2116c209dc" title="Returns a string describing the error code errcode.">RTPGetErrorString</a>(status) &lt;&lt; std::endl;
                exit(-1);
        }
        
        <span class="comment">//</span>
        <span class="comment">// Inspect incoming data here</span>
        <span class="comment">//</span>
        
        <a class="code" href="classRTPTime.html#0ccccb0a8cb82bc4591911dbf17e5f0b" title="This function waits the amount of time specified in delay.">RTPTime::Wait</a>(delay);
        
        <a class="code" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a> t = <a class="code" href="classRTPTime.html#de5ba279f814edb9894ced694845fdad" title="Returns an RTPTime instance representing the current wallclock time.">RTPTime::CurrentTime</a>();
        t -= starttime;
        <span class="keywordflow">if</span> (t &gt; <a class="code" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a>(60.0))
                done = <span class="keyword">true</span>;
 }
</pre></div><p>
Information about participants in the session, packet retrieval etc, has to be done between calls to the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> member functions BeginDataAccess and EndDataAccess. This ensures that the background thread doesn't try to change the same data you're trying to access. We'll iterate over the participants using the GotoFirstSource and GotoNextSource member functions. Packets from the currently selected participant can be retrieved using the GetNextPacket member function which returns a pointer to an instance of the <a class="el" href="classRTPPacket.html" title="Represents an RTP Packet.">RTPPacket</a> class. When you don't need the packet anymore, it has to be deleted. The processing of incoming data will then be as follows:<p>
<div class="fragment"><pre class="fragment"> session.<a class="code" href="classRTPSession.html#262d1afa20aaa5dde8a798dbc4056ae4" title="The following member functions (till EndDataAccess}) need to be accessed between...">BeginDataAccess</a>();
 <span class="keywordflow">if</span> (session.<a class="code" href="classRTPSession.html#adce56dd9a5e345a0cce2674135c135d" title="Starts the iteration over the participants by going to the first member in the table...">GotoFirstSource</a>())
 {
        <span class="keywordflow">do</span>
        {
                <a class="code" href="classRTPPacket.html" title="Represents an RTP Packet.">RTPPacket</a> *packet;
                <span class="keywordflow">while</span> ((packet = session.<a class="code" href="classRTPSession.html#267350e7f289192fa13683b2bf5ee3b5" title="Extracts the next packet from the received packets queue of the current participant...">GetNextPacket</a>()) != 0)
                {
                        std::cout &lt;&lt; <span class="stringliteral">"Got packet with extended sequence number "</span> 
                                  &lt;&lt; packet-&gt;<a class="code" href="classRTPPacket.html#8d687e10420f7afccb147ea6a637b2bd" title="Returns the extended sequence number of the packet.">GetExtendedSequenceNumber</a>() 
                                          &lt;&lt; <span class="stringliteral">" from SSRC "</span> &lt;&lt; packet-&gt;<a class="code" href="classRTPPacket.html#8bfb5c302310485fed36bfab0b0ac6d8" title="Returns the SSRC identifier stored in this packet.">GetSSRC</a>() 
                                          &lt;&lt; std::endl;
                        session.<a class="code" href="classRTPSession.html#58850b96177ed858747070f9e03c4cd6" title="Frees the memory used by p.">DeletePacket</a>(packet);
                }
        } <span class="keywordflow">while</span> (session.<a class="code" href="classRTPSession.html#0652c466c930403ee51dc842396ce9a6" title="Sets the current source to be the next source in the table.">GotoNextSource</a>());
 }
 session.<a class="code" href="classRTPSession.html#e2b77e9c6ff090eeb8b7d2d9074df87e" title="See BeginDataAccess.">EndDataAccess</a>();
</pre></div><p>
Information about the currently selected source can be obtained by using the GetCurrentSourceInfo member function of the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class. This function returns a pointer to an instance of <a class="el" href="classRTPSourceData.html" title="Describes an entry in the RTPSources source table.">RTPSourceData</a> which contains all information about that source: sender reports from that source, receiver reports, SDES info etc.<p>
When the main loop is finished, we'll send a BYE packet to inform other participants of our departure and clean up the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class. Also, we want to wait at most 10 seconds for the BYE packet to be sent, otherwise we'll just leave the session without sending a BYE packet.<p>
<div class="fragment"><pre class="fragment"> delay = <a class="code" href="classRTPTime.html" title="This class is used to specify wallclock time, delay intervals etc.">RTPTime</a>(10.0);
 session.<a class="code" href="classRTPSession.html#d682c2b85413413b20341a7e3ef0b668" title="Sends a BYE packet and leaves the session.">BYEDestroy</a>(delay,<span class="stringliteral">"Time's up"</span>,9);
</pre></div><p>
The complete code of the program is given in <code>example2.cpp</code>.<h2><a class="anchor" name="errors">
Error codes</a></h2>
Unless specified otherwise, functions with a return type <code>int</code> will return a negative value when an error occurred and zero or a positive value upon success. A description of the error code can be obtained by using the RTPGetErrorString function, declared in <a class="el" href="rtperrors_8h.html">rtperrors.h</a><h2><a class="anchor" name="memory">
Memory management</a></h2>
You can write you own memory manager by deriving a class from <a class="el" href="classRTPMemoryManager.html" title="A memory manager.">RTPMemoryManager</a>. The following example shows a very basic implementation.<p>
<div class="fragment"><pre class="fragment"> <span class="keyword">class </span>MyMemoryManager : <span class="keyword">public</span> <a class="code" href="classRTPMemoryManager.html" title="A memory manager.">RTPMemoryManager</a>
 {
 <span class="keyword">public</span>:
        MyMemoryManager() { }
        ~MyMemoryManager() { }
        
        <span class="keywordtype">void</span> *AllocateBuffer(<span class="keywordtype">size_t</span> numbytes, <span class="keywordtype">int</span> memtype)
        {
                <span class="keywordflow">return</span> malloc(numbytes);
        }

        <span class="keywordtype">void</span> FreeBuffer(<span class="keywordtype">void</span> *p)
        {
                free(p);
        }
 };
</pre></div><p>
In the constructor of <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a>, you can specify that you would like to use this memory manager:<p>
<div class="fragment"><pre class="fragment"> MyMemoryManager mgr;
 <a class="code" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> session(&amp;mgr);
</pre></div><p>
Now, all memory allocation and deallocation will be done using the AllocateBuffer and FreeBuffer implementations of <code>mgr</code>.<p>
The second parameter of the <a class="el" href="classRTPMemoryManager.html#a8950b1a64bc22a267fb390ab8ec8d2d" title="Called to allocate numbytes of memory.">RTPMemoryManager::AllocateBuffer</a> member function indicates what the purpose is of this memory block. This allows you to handle different kinds of data in different ways.<p>
With the introduction of the memory management system, the <a class="el" href="classRTPSession.html" title="High level class for using RTP.">RTPSession</a> class was extended with member function <a class="el" href="classRTPSession.html#58850b96177ed858747070f9e03c4cd6" title="Frees the memory used by p.">RTPSession::DeletePacket</a> and <a class="el" href="classRTPSession.html#3c3fb0ac122ace411d6c22704ca6365d" title="Frees the memory used by the transmission information inf.">RTPSession::DeleteTransmissionInfo</a>. These functions should be used to deallocate <a class="el" href="classRTPPacket.html" title="Represents an RTP Packet.">RTPPacket</a> instances and <a class="el" href="classRTPTransmissionInfo.html" title="Base class for additional information about the transmitter.">RTPTransmissionInfo</a> instances respectively.<h2><a class="anchor" name="contact">
Contact</a></h2>
If you have any questions, remarks or requests about the library or if you think you've discovered a bug, you can contact me at <code>jori</code>(<code>dot</code>)<code>liesenborgs</code>(<code>at</code>)<code>gmail</code>(<code>dot</code>)<code>com</code> <p>
The home page of the library is <a href="http://research.edm.uhasselt.be/jori/jrtplib/jrtplib.html">http://research.edm.uhasselt.be/jori/jrtplib/jrtplib.html</a><p>
There is also a mailing list for the library. To subscribe to the list, send an e-mail with the text <code>subscribe</code> <code>jrtplib</code> as the message body (not the subject) to <code>majordomo</code>(<code>at</code>)<code>edm</code>(<code>dot</code>)<code>uhasselt</code>(<code>dot</code>)<code>be</code> and you'll receive further instructions. </div>
<hr size="1"><address style="text-align: right;"><small>Generated on Sun Jul 26 09:42:07 2009 for jrtplib by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.9 </small></address>
</body>
</html>