root/rat/trunk/playout_calc.c @ 2914

Revision 2914, 3.6 KB (checked in by ucacoxh, 14 years ago)
  • Revised skew adaptation. Now compares transit time in use with transit average, instead of monitoring playout buffer length which is tainted by packet losses.
  • Playout variable now refers to playout offset only. Formerly included difference between sources time and our time too.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:    playout_calc.c
3 * PROGRAM: RAT
4 * AUTHOR:  Orion Hodson
5 *
6 * $Revision$
7 * $Date$
8 *
9 * Copyright (c) 1999 University College London
10 * All rights reserved.
11 *
12 */
13
14#include "config_unix.h"
15#include "config_win32.h"
16#include "debug.h"
17#include "ts.h"
18#include "session.h"
19#include "cushion.h"
20#include "pdb.h"
21#include "playout_calc.h"
22
23static ts_t
24playout_variable_component(session_t *sp, pdb_entry_t *e)
25/*****************************************************************************/
26/* playout_variable component works out the variable components that RAT has */
27/* in it's playout calculation.  It works returns the maximum of:            */
28/* the interpacket gap, the cushion size, and the user requested limits on   */
29/* the playout point.                                                        */
30/*****************************************************************************/
31{
32        u_int32 var32, freq, cushion;
33
34        freq  = get_freq(e->clock);
35        var32 = e->inter_pkt_gap / 2;
36
37        cushion = cushion_get_size(sp->cushion);
38        if (var32 < cushion) {
39                var32 = cushion;
40        }
41       
42        if (sp->limit_playout) {
43                u_int32 minv, maxv;
44                minv = sp->min_playout * freq / 1000;
45                maxv = sp->max_playout * freq / 1000;
46                var32 = max(minv, var32);
47                var32 = min(maxv, var32);
48        }
49
50        return ts_map32(freq, var32);
51}
52
53
54ts_t
55playout_calc(session_t *sp, u_int32 ssrc, ts_t transit, int new_spurt)
56/*****************************************************************************/
57/* The primary purpose of this function is to calculate the playout point    */
58/* for new talkspurts (new_spurt).  It also maintains the jitter and transit */
59/* time estimates from the source to us.  The value returned is the local    */
60/* playout time.                                                             */
61/*****************************************************************************/
62{
63        pdb_entry_t *e;
64        ts_t         var;
65
66        pdb_item_get(sp->pdb, ssrc, &e);
67        assert(e != NULL);
68
69        if (new_spurt == TRUE) {
70                debug_msg("New talkspurt\n");
71                /* Get RAT specific variable playout component               */
72                var = playout_variable_component(sp, e);
73                /* Use the larger of jitter and variable playout component.  */
74                if (ts_gt(var, e->jitter)) {
75                        e->playout = var;
76                } else {
77                        e->playout = e->jitter;
78                }
79                debug_msg("Playout offset (%08lu)\n", e->playout.ticks);
80                e->transit     = transit;
81                e->avg_transit = transit;
82        } else {
83                ts_t delta_transit;
84                /* delta_transit is abs((s[j+1] - d[j+1]) - (s[j] - d[j]))  */
85                delta_transit   = ts_abs_diff(transit, e->last_transit);
86                /* Update jitter estimate using                             */
87                /*                  jitter = (7/8)jitter + (1/8) new_jitter */
88                e->jitter = ts_mul(e->jitter, 7);
89                e->jitter = ts_add(e->jitter, delta_transit);     
90                e->jitter = ts_div(e->jitter, 8);
91
92                delta_transit = ts_abs_diff(transit, e->avg_transit);
93                if (ts_gt(transit, e->avg_transit)) {
94                        e->avg_transit = ts_add(e->avg_transit, ts_div(delta_transit,16));
95                } else {
96                        e->avg_transit = ts_sub(e->avg_transit, ts_div(delta_transit,16));
97                }
98        }
99
100        return e->playout;
101}
Note: See TracBrowser for help on using the browser.