~ubuntu-branches/ubuntu/quantal/linphone/quantal

« back to all changes in this revision

Viewing changes to mediastreamer/mstimer.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2004-06-30 13:58:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040630135816-wwx75gdlodkqbabb
Tags: upstream-0.12.2
ImportĀ upstreamĀ versionĀ 0.12.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 /*
 
2
  The mediastreamer library aims at providing modular media processing and I/O
 
3
        for linphone, but also for any telephony application.
 
4
  Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
 
5
                                                                                
 
6
  This library is free software; you can redistribute it and/or
 
7
  modify it under the terms of the GNU Lesser General Public
 
8
  License as published by the Free Software Foundation; either
 
9
  version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
  This library is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
  Lesser General Public License for more details.
 
15
 
 
16
  You should have received a copy of the GNU Lesser General Public
 
17
  License along with this library; if not, write to the Free Software
 
18
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
 
 
22
#include "mstimer.h"
 
23
#include <unistd.h>
 
24
#include <sys/types.h>
 
25
#include <sys/time.h>
 
26
#include <signal.h>
 
27
 
 
28
static MSTimerClass *ms_timer_class=NULL;
 
29
 
 
30
static void dummy_handler(int signum)
 
31
{
 
32
        //posix_timer_time+=POSIXTIMER_INTERVAL/1000;
 
33
        //alarm_received++;
 
34
        //printf("tick !!!\n");
 
35
}
 
36
 
 
37
static void posix_timer_init(MSTimer *posix_timer)
 
38
{
 
39
        struct itimerval timer;
 
40
        sigset_t set;
 
41
        /* block the SIGALRM signal 
 
42
        sigemptyset(&set);
 
43
        sigaddset(&set,SIGALRM);
 
44
        sigprocmask(SIG_BLOCK,&set,NULL);*/
 
45
        
 
46
        timer.it_value.tv_sec=posix_timer->interval.tv_sec;
 
47
        timer.it_value.tv_usec=posix_timer->interval.tv_usec;
 
48
        timer.it_interval.tv_sec=posix_timer->interval.tv_sec;
 
49
        timer.it_interval.tv_usec=posix_timer->interval.tv_usec;
 
50
        
 
51
        signal(SIGALRM,dummy_handler);
 
52
        setitimer(ITIMER_REAL,&timer,NULL);
 
53
        posix_timer->state=MS_TIMER_RUNNING;
 
54
        gettimeofday(&posix_timer->orig,NULL);
 
55
        posix_timer->late_ticks=0;
 
56
        posix_timer->time=0;
 
57
}
 
58
 
 
59
 
 
60
 
 
61
static void posix_timer_do(MSTimer *posix_timer)
 
62
{
 
63
        sigset_t set;
 
64
        guint32 time;
 
65
        gint32 diff;
 
66
        
 
67
        if (posix_timer->late_ticks>0){
 
68
                posix_timer->late_ticks--;
 
69
                posix_timer->time+=posix_timer->milisec;
 
70
                MS_SYNC(posix_timer)->time=posix_timer->time;
 
71
                return;
 
72
        }
 
73
        
 
74
        sigfillset(&set);
 
75
        sigdelset(&set,SIGALRM);
 
76
        
 
77
        //printf("time=%i\n",time);
 
78
        sigsuspend(&set);
 
79
                /* here we receive the signal */
 
80
        posix_timer->time+=posix_timer->milisec;
 
81
        MS_SYNC(posix_timer)->time=posix_timer->time;
 
82
        
 
83
        gettimeofday(&posix_timer->cur,NULL);
 
84
        time=((posix_timer->cur.tv_usec-posix_timer->orig.tv_usec)/1000 ) + ((posix_timer->cur.tv_sec-posix_timer->orig.tv_sec)*1000 );
 
85
        diff=time-posix_timer->time;
 
86
        
 
87
        if (diff> posix_timer->milisec){
 
88
                posix_timer->late_ticks=diff/posix_timer->milisec;
 
89
                if (posix_timer->late_ticks>5) g_warning("MSTimer: must catchup %i ticks.",posix_timer->late_ticks);
 
90
                return;
 
91
        }
 
92
}
 
93
 
 
94
static void posix_timer_uninit(MSTimer *posix_timer)
 
95
{
 
96
        struct itimerval timer;
 
97
        /* unset the timer */
 
98
        memset(&timer,0,sizeof(struct itimerval));
 
99
        setitimer(ITIMER_REAL,&timer,NULL);
 
100
        posix_timer->state=MS_TIMER_STOPPED;
 
101
}
 
102
 
 
103
 
 
104
void ms_timer_init(MSTimer *sync)
 
105
{
 
106
        ms_sync_init(MS_SYNC(sync));
 
107
        MS_SYNC(sync)->attached_filters=sync->filters;
 
108
        memset(sync->filters,0,MSTIMER_MAX_FILTERS*sizeof(MSFilter*));
 
109
        MS_SYNC(sync)->samples_per_tick=160;
 
110
        ms_timer_set_interval(sync,20);
 
111
        sync->state=MS_TIMER_STOPPED;
 
112
}
 
113
 
 
114
void ms_timer_class_init(MSTimerClass *klass)
 
115
{
 
116
        ms_sync_class_init(MS_SYNC_CLASS(klass));
 
117
        MS_SYNC_CLASS(klass)->max_filters=MSTIMER_MAX_FILTERS;
 
118
        MS_SYNC_CLASS(klass)->synchronize=(MSSyncSyncFunc)ms_timer_synchronize;
 
119
        MS_SYNC_CLASS(klass)->destroy=(MSSyncDestroyFunc)ms_timer_destroy;
 
120
        /* no need to overload these function*/
 
121
        MS_SYNC_CLASS(klass)->attach=ms_sync_attach_generic;
 
122
        MS_SYNC_CLASS(klass)->detach=ms_sync_detach_generic;
 
123
}
 
124
 
 
125
void ms_timer_destroy(MSTimer *timer)
 
126
{
 
127
        g_free(timer);
 
128
}
 
129
 
 
130
 
 
131
void ms_timer_synchronize(MSTimer *timer)
 
132
{
 
133
        //printf("ticks=%i \n",MS_SYNC(timer)->ticks);
 
134
        if (timer->state==MS_TIMER_STOPPED){
 
135
                posix_timer_init(timer);
 
136
                //printf("ms_timer_synchronize: starting timer.\n");
 
137
        }
 
138
        else posix_timer_do(timer);
 
139
        return;
 
140
}
 
141
 
 
142
 
 
143
MSSync *ms_timer_new()
 
144
{
 
145
        MSTimer *timer;
 
146
        
 
147
        timer=g_malloc(sizeof(MSTimer));
 
148
        ms_timer_init(timer);
 
149
        if (ms_timer_class==NULL)
 
150
        {
 
151
                ms_timer_class=g_new(MSTimerClass,1);
 
152
                ms_timer_class_init(ms_timer_class);
 
153
        }
 
154
        MS_SYNC(timer)->klass=MS_SYNC_CLASS(ms_timer_class);
 
155
        return(MS_SYNC(timer));
 
156
}
 
157
 
 
158
void ms_timer_set_interval(MSTimer *timer, int milisec)
 
159
{
 
160
        
 
161
        MS_SYNC(timer)->ticks=0;
 
162
        MS_SYNC(timer)->interval=milisec;
 
163
        timer->interval.tv_sec=milisec/1000;
 
164
        timer->interval.tv_usec=(milisec % 1000)*1000;
 
165
        timer->milisec=milisec;
 
166
        
 
167
        
 
168
}