Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

vatrcvr.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) Xerox Corporation 1997. All rights reserved.
00004  *
00005  * License is granted to copy, to use, and to make and to use derivative
00006  * works for research and evaluation purposes, provided that Xerox is
00007  * acknowledged in all documentation pertaining to any such copy or
00008  * derivative work. Xerox grants no other licenses expressed or
00009  * implied. The Xerox trade name should not be used in any advertising
00010  * without its written permission. 
00011  *
00012  * XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
00013  * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
00014  * FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
00015  * express or implied warranty of any kind.
00016  *
00017  * These notices must be retained in any copies of any part of this
00018  * software. 
00019  */
00020 
00021 /*
00022  * Copyright (c) 1995 The Regents of the University of California.
00023  * All rights reserved.
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions
00027  * are met:
00028  * 1. Redistributions of source code must retain the above copyright
00029  *    notice, this list of conditions and the following disclaimer.
00030  * 2. Redistributions in binary form must reproduce the above copyright
00031  *    notice, this list of conditions and the following disclaimer in the
00032  *    documentation and/or other materials provided with the distribution.
00033  * 3. All advertising materials mentioning features or use of this software
00034  *    must display the following acknowledgement:
00035  *      This product includes software developed by the Network Research
00036  *      Group at Lawrence Berkeley National Laboratory.
00037  * 4. Neither the name of the University nor of the Laboratory may be used
00038  *    to endorse or promote products derived from this software without
00039  *    specific prior written permission.
00040  *
00041  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00042  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00043  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00044 */
00045 
00046 #ifndef lint
00047 static const char  rcsid[] =
00048 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/vatrcvr.cc,v 1.6 2000/09/01 03:04:08 haoboy Exp $";
00049 #endif
00050 
00051 #ifndef WIN32
00052 #include <sys/time.h>
00053 #endif
00054 #include "agent.h"
00055 #include "rtp.h"
00056 #include "adaptive-receiver.h"
00057 #include "vat.h"
00058 
00059 //Most of this code is taken from the decoder.cc file of the publicly available
00060 //vat code with some minor midifications.
00061 
00062 class VatRcvr : public AdaptiveRcvr {
00063 public:
00064         VatRcvr();
00065 protected:
00066         int adapt(Packet *pkt, u_int32_t time);
00067         void count(int statno);
00068         u_int32_t hostoffset_;
00069         int32_t var_; //variance in  this host's interarrival time
00070         u_int32_t playout_; // playout delay (in media units)
00071         int maxdel_;
00072         int block_size_;
00073         int lecture_mode_;
00074         u_int32_t lastrecv_;
00075         u_int32_t predicted_drop_;
00076         int delvar_;
00077         /*XXX*/
00078 #define MAXSTAT 16
00079         struct statcntr {
00080                 const char* name;
00081                 u_int cnt;
00082         } stat_[MAXSTAT];
00083         int nstat_;
00084 };
00085 
00086 
00087 inline void VatRcvr::count(int statno)
00088 {
00089         ++stat_[statno].cnt;
00090 }
00091 
00092 
00093 inline int absdiff(int x, int y)
00094 {
00095         register int r = y - x;
00096         return (r < 0? -r : r);
00097 }
00098 
00099 static inline int newoffset(
00100         int nvar,
00101         int playout,
00102         int maxdel, int mindel, int lecture)
00103 {
00104         register int offset = nvar;
00105         if (offset > maxdel)
00106                 offset = maxdel;
00107         register int diff = playout - offset;
00108 
00109         if (diff > 0) {
00110                 // offset going down: in LectureMode, drop at most
00111                 // one frametime per talkspurt.  In ConferenceMode,
00112                 // drop at most 1/2 of difference.
00113                 if (lecture) {
00114                         if (diff > FRAMESIZE) {
00115                                 if (playout > (maxdel * 3) / 4 &&
00116                                     diff > 10 * FRAMESIZE)
00117                                         diff = 5 * FRAMESIZE;
00118                                 else
00119                                         diff = FRAMESIZE;
00120                         }
00121                 } else
00122                         diff >>= 1;
00123                 offset = playout - diff;
00124         } else if (-diff > maxdel) {
00125                 // offset going way up: only allow 3/4 of max.
00126                 offset = (maxdel * 3) / 4;
00127         }
00128         if (offset > (maxdel * 7) / 8)
00129                 offset = (maxdel * 7) / 8;
00130         else if (offset < mindel)
00131                 offset = mindel;
00132         return (offset);
00133 }
00134 
00135 
00136 
00137 int VatRcvr::adapt(Packet *pkt, u_int32_t local_clock)
00138 {
00139         hdr_cmn* ch = hdr_cmn::access(pkt);
00140         register u_int32_t tstamp = (int)ch->timestamp();
00141         register int hoff = (int)hostoffset_;
00142         register int offset = (tstamp + hoff - local_clock) &~ 3;
00143         hdr_rtp *rh = hdr_rtp::access(pkt);
00144         int new_ts = rh->flags() & RTP_M ;
00145 
00146         //struct timeval tv;
00147         //static long int last;
00148         
00149         /*    printf("%1d %10d %10d\n", new_ts ? 1: 0, tstamp, local_clock);*/
00150         
00151         /* printf("%u\n", tstamp); */
00152         
00153         //gettimeofday(&tv, NULL);
00154         //last = tv.tv_usec - last;
00155         //if (last < 0)
00156         //      last += 1000000;
00157         /*
00158           printf("%u %u %u ==> %d\n", tstamp, hoff, local_clock, offset);
00159           printf("%u %d\n", tv.tv_usec, last);
00160           */
00161         //last = tv.tv_usec;
00162         /* printf("%u ==> %d\n", local_clock, offset); */
00163         
00164         if (hoff == 0 || new_ts) {
00165                 /*  if (hoff == 0) {  */
00166                 
00167                 /* printf("TS: var = %d playback = %d", var_ >> (VAR_FILTER + 3), 
00168                    playout_ >> (PLAYO_FILTER + 3)); */
00169                 /*
00170                  * start of new talk spurt --
00171                  * use accumulated variance to compute new offset if
00172                  * this would make a significant change.  We change if
00173                  *  - the variance is currently 'small', or
00174                  *  - the change would be a least a packet time
00175                  */
00176                 register int nvar = var_ >> (VAR_FILTER - VAR_MULT);
00177                 offset = playout_ >> PLAYO_FILTER;
00178                 if (nvar < 3*FRAMESIZE || absdiff(nvar, offset) >= FRAMESIZE) {
00179                         offset = newoffset(nvar, offset, maxdel_, 
00180                                            block_size_, lecture_mode_);
00181                         /*
00182                          * assume that a talk spurt starts with TALK_LEAD
00183                          * samples of history & subtract them off if possible.
00184                          */
00185                         
00186                         /* CHANGED THIS PART OF VAT CODE AS WELL */
00187                         if (new_ts) {
00188                                 offset -= 4 * FRAMESIZE;
00189                                 if (offset < block_size_)
00190                                         offset = block_size_;
00191                                 
00192                         }
00193                 }
00194                 hostoffset_ = local_clock - tstamp + offset;
00195                 /* printf(" new playback = %d\n", offset >> 3); */
00196         } else if (offset < 0 || offset > maxdel_) {
00197                 /* printf("LP: late by %d var = %d playback = %d", (0 - (offset >> 3)), 
00198                    var_ >> (VAR_FILTER + 3), playout_ >> (PLAYO_FILTER + 3)); */
00199                 /*
00200                  * packet out of range -- if last packet also out of
00201                  * range or if the delay would increase, resync.
00202                  */
00203                 if (offset < 0 || predicted_drop_ == tstamp) {
00204                         offset = newoffset(var_ >> (VAR_FILTER - VAR_MULT),
00205                                            playout_ >> PLAYO_FILTER,
00206                                            maxdel_, block_size_,
00207                                            lecture_mode_);
00208                         hostoffset_ = local_clock - tstamp + offset;
00209                 } else {
00210                         /* printf("late packet\n"); */
00211                         predicted_drop_ = tstamp + block_size_;
00212                         lastrecv_ = tstamp - local_clock;
00213                         count(STAT_LATE);
00214                         return (-1);
00215                 }
00216                 /* printf(" new playback = %d\n", offset >> 3); */
00217         } else {
00218                 // packet in range, update interarrival var. est.
00219                 register int nvar = var_;
00220                 register int off = tstamp - local_clock - lastrecv_;
00221                 /* printf("offset =  %3d", off >> 3);  */
00222                 if (off < 0)
00223                         off = -off;
00224                 off -= (nvar >> VAR_FILTER);
00225                 var_ = nvar + off;
00226                 /* printf(" var =  %3d", var_ >> 8);  */
00227         }
00228         lastrecv_ = tstamp - local_clock;
00229         register u_int avgplay = playout_;
00230         playout_ = avgplay + (offset - (avgplay >> PLAYO_FILTER));
00231         /* printf(" offset = %3d avg playout = %3d", offset >> 3, playout_ >> 8);  */
00232         offset &= ~3;
00233         delvar_ = var_ >> VAR_FILTER;
00234         /* printf("\n"); */
00235         return (offset);
00236         
00237 }
00238 
00239 
00240 
00241 static class VatRcvrClass : public TclClass {
00242 public:
00243         VatRcvrClass() : TclClass("Agent/VatRcvr") {}
00244         TclObject* create(int, const char*const*) {
00245                 return (new VatRcvr());
00246 
00247         }
00248 } class_vat_rcvr;
00249 
00250 
00251 VatRcvr::VatRcvr() : 
00252         hostoffset_(0),
00253         var_(INITIAL_OFFSET << (VAR_FILTER - VAR_MULT)),
00254         playout_(INITIAL_OFFSET << PLAYO_FILTER),
00255         maxdel_(8000*6),
00256         block_size_(FRAMESIZE),
00257         lecture_mode_(0),
00258         lastrecv_(0),
00259         predicted_drop_(~0),
00260         nstat_(0)
00261 {
00262 
00263         for (int i = 0; i < MAXSTAT; ++i) {
00264                 stat_[i].name = 0;
00265                 stat_[i].cnt = 0;
00266         }
00267         stat_[STAT_LATE].name = "Late-Pkts";
00268         nstat_ = 1;
00269 }

Generated on Tue Apr 20 12:14:38 2004 for NS2.26SourcesOriginal by doxygen 1.3.3