Mahdi,<br>
<br><br><div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br><br>Dear Ross,<br><br>RTCP "RR" packets are reaching the server but the
<br>program doesn't call the taskfunction and doesn't<br>update videoSink->transmissionStatsDB().<br>I can see the packet RTCP RR using ethereal.<br><br>Thanks.<br><br>/**********<br>This library is free software; you can redistribute it
<br>and/or modify it under<br>the terms of the GNU Lesser General Public License as<br>published by the<br>Free Software Foundation; either version 2.1 of the<br>License, or (at your<br>option) any later version. (See<br>
<<a href="http://www.gnu.org/copyleft/lesser.html">http://www.gnu.org/copyleft/lesser.html</a>>.)<br><br>This library is distributed in the hope that it will<br>be useful, but WITHOUT<br>ANY WARRANTY; without even the implied warranty of
<br>MERCHANTABILITY or FITNESS<br>FOR A PARTICULAR PURPOSE. See the GNU Lesser General<br>Public License for<br>more details.<br><br>You should have received a copy of the GNU Lesser<br>General Public License<br>along with this library; if not, write to the Free
<br>Software Foundation, Inc.,<br>59 Temple Place, Suite 330, Boston, MA 02111-1307<br>USA<br>**********/<br>// Copyright (c) 1996-2005, Live Networks, Inc. All<br>rights reserved<br>// A test program that reads a MPEG-2 Transport Stream
<br>file,<br>// and streams it using RTP<br>// main program<br><br>#include "liveMedia.hh"<br>#include "BasicUsageEnvironment.hh"<br>#include "GroupsockHelper.hh"<br>#include "RTCP.hh"
<br><br>#define ADVANCE(n) pkt += (n); packetSize -= (n)<br>// To stream using "source-specific multicast" (SSM),<br>uncomment the following:<br>//#define USE_SSM 1<br>//#define IMPLEMENT_RTSP_SERVER 1<br><br>#ifdef USE_SSM
<br>Boolean const isSSM = True;<br>#else<br>Boolean const isSSM = False;<br>#endif<br><br>// To set up an internal RTSP server, uncomment the<br>following:<br>//#define IMPLEMENT_RTSP_SERVER 1<br>// (Note that this RTSP server works for multicast
<br>only)<br><br>#define TRANSPORT_PACKET_SIZE 188<br>#define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7<br>// The product of these two numbers must be enough to<br>fit within a network packet<br><br>UsageEnvironment* env;<br>
char const* inputFileName = "tmp.mpg";<br>FramedSource* videoSource;<br>RTPSink* videoSink;<br>RTCPInstance* rtcp;<br>//RTPTransmissionStats* rtpstats;<br><br>// char* destinationAddressStr = "<a href="http://127.0.0.1">
127.0.0.1</a>";<br> char* destinationAddressStr = "<a href="http://239.255.42.42">239.255.42.42</a>";<br> unsigned short rtpPortNum = 1234;<br> char* rtpPortNum_chai = "1234";<br> unsigned short rtcpPortNum = 1235;
<br> char* rtcpPortNum_chai = "1235";<br> unsigned char ttl = 7; // low, in case routers don't<br>admin scope<br><br>void play(); // forward<br>void taskfunc_RR(void* /*clientData*/);<br>void taskfunc_SR(void* /*clientData*/);
<br><br>int main() {<br> // Begin by setting up our usage environment:<br> TaskScheduler* scheduler =<br>BasicTaskScheduler::createNew();<br> env = BasicUsageEnvironment::createNew(*scheduler);<br><br> // Create 'groupsocks' for RTP and RTCP:
<br>/* char* destinationAddressStr<br>#ifdef USE_SSM<br> = "<a href="http://127.0.0.1">127.0.0.1</a>";<br>#else<br> = "<a href="http://127.0.0.1">127.0.0.1</a>";<br>/*#ifdef USE_SSM<br> = "
<a href="http://232.255.42.42">232.255.42.42</a>";<br>#else<br> = "<a href="http://239.255.42.42">239.255.42.42</a>";*/<br> // Note: This is a multicast address. If you wish<br>to stream using<br> // unicast instead, then replace this string with
<br>the unicast address<br> // of the (single) destination. (You may also need<br>to make a similar<br> // change to the receiver program.)<br>//#endif<br>/* const unsigned short rtpPortNum = 1234;<br> const unsigned short rtcpPortNum = rtpPortNum+1;
<br> const unsigned char ttl = 7; // low, in case routers<br>don't admin scope<br>*/<br> struct in_addr destinationAddress;<br> destinationAddress.s_addr =<br>our_inet_addr(destinationAddressStr);<br> const Port rtpPort(rtpPortNum);
<br> const Port rtcpPort(rtcpPortNum);<br><br> Groupsock rtpGroupsock(*env, destinationAddress,<br>rtpPort, ttl);<br> Groupsock rtcpGroupsock(*env, destinationAddress,<br>rtcpPort, ttl);<br>#ifdef USE_SSM<br> rtpGroupsock.multicastSendOnly
();<br> rtcpGroupsock.multicastSendOnly();<br>#endif<br><br> // Create an appropriate 'RTP sink' from the RTP<br>'groupsock':<br> videoSink =<br> SimpleRTPSink::createNew(*env, &rtpGroupsock, 33,<br>90000, "video", "mp2t",
<br>
1, True, False /*no 'M' bit*/);<br><br> // Create (and start) a 'RTCP instance' for this RTP<br>sink:<br> const unsigned estimatedSessionBandwidth = 5000; //<br>in kbps; for RTCP b/w share<br> const unsigned maxCNAMElen = 100;
<br> unsigned char CNAME[maxCNAMElen+1];<br> gethostname((char*)CNAME, maxCNAMElen);<br> CNAME[maxCNAMElen] = '\0'; // just in case<br>//#ifdef IMPLEMENT_RTSP_SERVER<br>//#endif<br> rtcp = RTCPInstance::createNew(*env, &rtcpGroupsock,
<br> estimatedSessionBandwidth,
CNAME,<br> videoSink,
NULL /* we're a server */, isSSM);<br> // Note: This starts RTCP running automatically<br><br>//rtpstats=RTPTransmissionStats::createNew(videoSink,<br><br>printf("mmm\n");<br>rtcp->setRRHandler(taskfunc_RR,rtcp);
<br>rtcp->setSRHandler(taskfunc_SR,rtcp);<br>printf("mmm\n");<br>#ifdef IMPLEMENT_RTSP_SERVER<br> RTSPServer* rtspServer =<br>RTSPServer::createNew(*env);<br> // Note that this (attempts to) start a server on
<br>the default RTSP server<br> // port: 554. To use a different port number, add<br>it as an extra<br> // (optional) parameter to the<br>"RTSPServer::createNew()" call above.<br> if (rtspServer == NULL) {<br>
*env << "Failed to create RTSP server: " <<<br>env->getResultMsg() << "\n";<br> exit(1);<br> }<br> ServerMediaSession* sms<br> = ServerMediaSession::createNew(*env,<br>
"testStream", inputFileName,<br>
"Session streamed by<br>\"testMPEG2TransportStreamer\"",<br>
isSSM);<br><br>sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink,<br>rtcp));<br> rtspServer->addServerMediaSession(sms);<br><br> char* url = rtspServer->rtspURL(sms);<br> *env << "Play this stream using the URL \"" << url
<br><< "\"\n";<br> delete[] url;<br>#endif<br><br> // Finally, start the streaming:<br> *env << "Beginning streaming...\n";<br> play();<br><br> env->taskScheduler().doEventLoop(); // does not
<br>return<br><br> return 0; // only to prevent compiler warning<br>}<br><br>void taskfunc_RR(void* clientData)<br>{<br>/* unsigned char * pkt;<br> unsigned packetSize=40;<br> pkt=rtcp->get_fInBuf();
<br> for (unsigned i = 0; i < packetSize; ++i) {<br> if (i%4 == 0) fprintf(stderr, " ");<br> fprintf(stderr, "%02x", pkt[i]);<br> }<br> fprintf(stderr, "\n");<br> ADVANCE(8);
<br> unsigned
lossStats =<br>ntohl(*(unsigned*)pkt); ADVANCE(4);<br> unsigned highestReceived =<br>ntohl(*(unsigned*)pkt); ADVANCE(4);<br> unsigned jitter =<br>ntohl(*(unsigned*)pkt); ADVANCE(4);<br> unsigned timeLastSR =
<br>ntohl(*(unsigned*)pkt); ADVANCE(4);<br> unsigned timeSinceLastSR =<br>ntohl(*(unsigned*)pkt); ADVANCE(4);<br> printf("%u\n",lossStats);<br> printf("jitter 0x%08x\n",jitter);*/
<br> int<br>packetLossRatio=-1,totNumPacketsLost=-1,jitterb=-1;<br> RTPTransmissionStatsDB::Iterator<br>statsIter(videoSink->transmissionStatsDB());<br> // Assume that there's only one SSRC source<br>(usually the case):
<br> RTPTransmissionStats* stats = statsIter.next();<br> if (stats != NULL) {<br> packetLossRatio = stats->packetLossRatio();<br> totNumPacketsLost = stats->totNumPacketsLost();<br> jitterb = stats->jitter();
<br> }<br>// printf("\n\nkBytesTotal %d\n",packetLossRatio);<br>// printf("totNumPacketsReceived<br>%d\n",totNumPacketsLost);<br> printf("jitter 0x%08x\n",jitterb);<br>
printf("RTCP RR recu\n");<br>}<br><br>void taskfunc_SR(void* clientData)<br>{<br>/* unsigned char * p;<br> unsigned packetSize=40;<br> p=rtcp->get_fInBuf();<br> for (unsigned i = 0; i < packetSize; ++i) {
<br> if (i%4 == 0) fprintf(stderr, " ");<br> fprintf(stderr, "%02x", p[i]);<br> }<br> fprintf(stderr, "\n");<br> /* int nb;<br> RTPTransmissionStatsDB& transmissionStatsDB =
<br>videoSink->transmissionStatsDB();<br> nb=transmissionStatsDB.numReceivers();<br> printf("%d\n",nb);*/<br>// printf("%s\n",clientData);<br> printf("RTCP SR recu\n");
<br>}<br><br>void afterPlaying(void* /*clientData*/) {<br> *env << "...done reading from file\n";<br><br> Medium::close(videoSource);<br> // Note that this also closes the input file that<br>this source read from.
<br><br> play();<br>}<br><br>void play() {<br> unsigned const inputDataChunkSize<br> =<br>TRANSPORT_PACKETS_PER_NETWORK_PACKET*TRANSPORT_PACKET_SIZE;<br><br> // Open the input file as a 'byte-stream file<br>source':
<br> ByteStreamFileSource* fileSource<br> = ByteStreamFileSource::createNew(*env,<br>inputFileName, inputDataChunkSize);<br> if (fileSource == NULL) {<br> *env << "Unable to open file \"" << inputFileName
<br> << "\" as a byte-stream file source\n";<br> exit(1);<br> }<br><br> // Create a 'framer' for the input source (to give<br>us proper inter-packet gaps):<br> videoSource =<br>MPEG2TransportStreamFramer::createNew(*env,
<br>fileSource);<br><br> // Finally, start playing:<br> *env << "Beginning to read from file...\n";<br> videoSink->startPlaying(*videoSource, afterPlaying,<br>videoSink);<br>}<br><br><br><br><br><br>
<br><br><br><br><br><br><br>___________________________________________________________________________<br>Faites
de Yahoo! votre page d'accueil sur le web pour retrouver directement
vos services pr?f?r?s : v?rifiez vos nouveaux mails, lancez vos
recherches et suivez l'actualit? en temps r?el.<br>Rendez-vous sur <a href="http://fr.yahoo.com/set">http://fr.yahoo.com/set</a><br><br><br>------------------------------<br><br>_______________________________________________
<br>live-devel mailing list<br><a href="mailto:live-devel@lists.live555.com">live-devel@lists.live555.com</a><br><a href="http://lists.live555.com/mailman/listinfo/live-devel">http://lists.live555.com/mailman/listinfo/live-devel
</a><br><br><br>End of live-devel Digest, Vol 30, Issue 33<br>******************************************<br></blockquote></div>Mahdi,<br>
u can take a look to "playCommon.cpp" where Ross implements the QoS printing feature based on (*sink->transmissionStatsDB).<br>
By the Way I have used the same implementation to implement a QoS
statistic module in VLC (but not released, this is just implmented in
our laboratory) and it works fine.<br>
<br>
Thnx <br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"></blockquote>
<br><br clear="all"><br>-- <br>Achraf Gazdar<br>CRISTAL LAB<br>ENSI, Tunisia