~ubuntu-branches/ubuntu/utopic/linphone/utopic-proposed

« back to all changes in this revision

Viewing changes to mediastreamer2/src/eventqueue.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2010-06-07 22:14:41 UTC
  • mfrom: (1.3.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100607221441-sbk1n7hp0mzu1rze
Tags: 3.3.1-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
mediastreamer2 library - modular sound and video processing and streaming
 
3
Copyright (C) 2010  Simon MORLAT (simon.morlat@linphone.org)
 
4
 
 
5
This program is free software; you can redistribute it and/or
 
6
modify it under the terms of the GNU General Public License
 
7
as published by the Free Software Foundation; either version 2
 
8
of the License, or (at your option) any later version.
 
9
 
 
10
This program is distributed in the hope that it will be useful,
 
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
GNU General Public License for more details.
 
14
 
 
15
You should have received a copy of the GNU General Public License
 
16
along with this program; if not, write to the Free Software
 
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
18
*/
 
19
 
 
20
#include "mediastreamer2/mseventqueue.h"
 
21
#include "mediastreamer2/msfilter.h"
 
22
 
 
23
#ifndef MS_EVENT_BUF_SIZE
 
24
#define MS_EVENT_BUF_SIZE 8192
 
25
#endif
 
26
 
 
27
struct _MSEventQueue{
 
28
        ms_mutex_t mutex; /*could be replaced by an atomic counter for freeroom*/
 
29
        uint8_t *rptr;
 
30
        uint8_t *wptr;
 
31
        uint8_t *endptr;
 
32
        uint8_t *lim;
 
33
        int freeroom;
 
34
        int size;
 
35
        uint8_t buffer[MS_EVENT_BUF_SIZE];
 
36
};
 
37
 
 
38
static void write_event(MSEventQueue *q, MSFilter *f, unsigned int ev_id, void *arg){
 
39
        int argsize=ev_id & 0xffff;
 
40
        int size=argsize+16;
 
41
        uint8_t *nextpos=q->wptr+size;
 
42
 
 
43
        if (q->freeroom<size){
 
44
                ms_error("Dropped event, no more free space in event buffer !");
 
45
                return;
 
46
        }
 
47
        
 
48
        if (nextpos>q->lim){
 
49
                /* need to wrap around */
 
50
                q->endptr=q->wptr;
 
51
                q->wptr=q->buffer;
 
52
                nextpos=q->wptr+size;
 
53
        }
 
54
        *(long*)q->wptr=(long)f;
 
55
        *(long*)(q->wptr+8)=(long)ev_id;
 
56
        if (argsize>0) memcpy(q->wptr+16,arg,argsize);
 
57
        q->wptr=nextpos;
 
58
        ms_mutex_lock(&q->mutex);
 
59
        q->freeroom-=size;
 
60
        ms_mutex_unlock(&q->mutex);
 
61
}
 
62
 
 
63
static bool_t read_event(MSEventQueue *q){
 
64
        int available=q->size-q->freeroom;
 
65
        if (available>0){
 
66
                MSFilter *f;
 
67
                unsigned int id;
 
68
                void *data;
 
69
                int argsize;
 
70
                int evsize;
 
71
                
 
72
                f=(MSFilter *)*(long*)(q->rptr);
 
73
                id=(unsigned int)*(long*)(q->rptr+8);
 
74
                argsize=id & 0xffff;
 
75
                evsize=argsize+16;
 
76
                data=q->rptr+16;
 
77
                if (f->notify!=NULL)
 
78
                        f->notify(f->notify_ud,id,argsize>0 ? data : NULL);
 
79
                q->rptr+=evsize;
 
80
                if (q->rptr>=q->endptr){
 
81
                        q->rptr=q->buffer;
 
82
                }
 
83
                ms_mutex_lock(&q->mutex);
 
84
                q->freeroom+=evsize;
 
85
                ms_mutex_unlock(&q->mutex);
 
86
                return TRUE;
 
87
        }
 
88
        return FALSE;
 
89
}
 
90
 
 
91
MSEventQueue *ms_event_queue_new(){
 
92
        MSEventQueue *q=ms_new0(MSEventQueue,1);
 
93
        int bufsize=MS_EVENT_BUF_SIZE;
 
94
        ms_mutex_init(&q->mutex,NULL);
 
95
        q->lim=q->buffer+bufsize;
 
96
        q->freeroom=bufsize;
 
97
        q->wptr=q->rptr=q->buffer;
 
98
        q->endptr=q->lim;
 
99
        q->size=bufsize;
 
100
        return q;
 
101
}
 
102
 
 
103
void ms_event_queue_destroy(MSEventQueue *q){
 
104
        ms_mutex_destroy(&q->mutex);
 
105
        ms_free(q);
 
106
}
 
107
 
 
108
static MSEventQueue *ms_global_event_queue=NULL;
 
109
 
 
110
void ms_set_global_event_queue(MSEventQueue *q){
 
111
        ms_global_event_queue=q;
 
112
}
 
113
 
 
114
void ms_event_queue_pump(MSEventQueue *q){
 
115
        while(read_event(q)){
 
116
        }
 
117
}
 
118
 
 
119
 
 
120
void ms_filter_notify(MSFilter *f, unsigned int id, void *arg){
 
121
        if (f->notify!=NULL){
 
122
                if (ms_global_event_queue==NULL){
 
123
                        /* synchronous notification */
 
124
                        f->notify(f->notify_ud,id,arg);                 
 
125
                }else{
 
126
                        write_event(ms_global_event_queue,f,id,arg);
 
127
                }
 
128
        }
 
129
}
 
130
 
 
131
void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){
 
132
        ms_filter_notify(f,id,NULL);
 
133
}