[Live-devel] live-devel Digest, Vol 30, Issue 33

Achraf Gazdar achraf.gazdar at gmail.com
Fri Apr 28 01:19:29 PDT 2006


Mahdi,



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

Thnx

>


--
Achraf Gazdar
CRISTAL LAB
ENSI, Tunisia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.live555.com/pipermail/live-devel/attachments/20060428/b3c6eb48/attachment.html 


More information about the live-devel mailing list