12024
|
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 #include <errno.h>
|
|
22 #include <string.h>
|
|
23 #include "msutils.h"
|
|
24 #include "msfifo.h"
|
|
25
|
|
26 MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset)
|
|
27 {
|
|
28 MSFifo *fifo;
|
|
29 gint saved_offset=MAX(r_gran+r_offset,w_offset);
|
|
30
|
|
31 g_return_val_if_fail(saved_offset<=(buf->size),NULL);
|
|
32 fifo=g_malloc(sizeof(MSFifo));
|
|
33 fifo->buffer=buf;
|
|
34 fifo->r_gran=r_gran;
|
|
35 fifo->w_gran=w_gran;
|
|
36 fifo->begin=fifo->wr_ptr=fifo->rd_ptr=buf->buffer+saved_offset;
|
|
37 fifo->readsize=0;
|
|
38 fifo->size=fifo->writesize=buf->size-saved_offset;
|
|
39 fifo->saved_offset= saved_offset;
|
|
40 fifo->r_end=fifo->w_end=buf->buffer+buf->size;
|
|
41 fifo->pre_end=fifo->w_end-saved_offset;
|
|
42 buf->ref_count++;
|
|
43 fifo->prev_data=NULL;
|
|
44 fifo->next_data=NULL;
|
|
45 ms_trace("fifo base=%x, begin=%x, end=%x, saved_offset=%i, size=%i"
|
|
46 ,fifo->buffer->buffer,fifo->begin,fifo->w_end,fifo->saved_offset,fifo->size);
|
|
47 return(fifo);
|
|
48 }
|
|
49
|
|
50 MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset,
|
|
51 gint min_fifo_size)
|
|
52 {
|
|
53 MSFifo *fifo;
|
|
54 MSBuffer *buf;
|
|
55 gint saved_offset=MAX(r_gran+r_offset,w_offset);
|
|
56 gint fifo_size;
|
|
57 if (min_fifo_size==0) min_fifo_size=w_gran;
|
|
58
|
|
59 /* we must allocate a fifo with a size multiple of min_fifo_size,
|
|
60 with a saved_offset */
|
|
61 if (min_fifo_size>MS_BUFFER_LARGE)
|
|
62 fifo_size=(min_fifo_size) + saved_offset;
|
|
63 else fifo_size=(6*min_fifo_size) + saved_offset;
|
|
64 buf=ms_buffer_new(fifo_size);
|
|
65 fifo=ms_fifo_new(buf,r_gran,w_gran,r_offset,w_offset);
|
|
66 ms_trace("fifo_size=%i",fifo_size);
|
|
67 return(fifo);
|
|
68 }
|
|
69
|
|
70 void ms_fifo_destroy( MSFifo *fifo)
|
|
71 {
|
|
72 g_free(fifo);
|
|
73 }
|
|
74
|
|
75 void ms_fifo_destroy_with_buffer(MSFifo *fifo)
|
|
76 {
|
|
77 ms_buffer_destroy(fifo->buffer);
|
|
78 ms_fifo_destroy(fifo);
|
|
79 }
|
|
80
|
|
81 gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
|
|
82 {
|
|
83 gchar *rnext;
|
|
84
|
|
85 *ret_ptr=NULL;
|
|
86 //ms_trace("ms_fifo_get_read_ptr: entering.");
|
|
87 g_return_val_if_fail(bsize<=fifo->r_gran,-EINVAL);
|
|
88
|
|
89 if (bsize>fifo->readsize)
|
|
90 {
|
|
91 ms_trace("Not enough data: bsize=%i, readsize=%i",bsize,fifo->readsize);
|
|
92 return (-ENODATA);
|
|
93 }
|
|
94
|
|
95 rnext=fifo->rd_ptr+bsize;
|
|
96 if (rnext<=fifo->r_end){
|
|
97
|
|
98 *ret_ptr=fifo->rd_ptr;
|
|
99 fifo->rd_ptr=rnext;
|
|
100 }else{
|
|
101 int unread=fifo->r_end-fifo->rd_ptr;
|
|
102 *ret_ptr=fifo->begin-unread;
|
|
103 memcpy(fifo->buffer->buffer,fifo->r_end-fifo->saved_offset,fifo->saved_offset);
|
|
104 fifo->rd_ptr=(char*)(*ret_ptr) + bsize;
|
|
105 fifo->r_end=fifo->w_end; /* this is important ! */
|
|
106 ms_trace("moving read ptr to %x",fifo->rd_ptr);
|
|
107
|
|
108 }
|
|
109 /* update write size*/
|
|
110 fifo->writesize+=bsize;
|
|
111 fifo->readsize-=bsize;
|
|
112 return bsize;
|
|
113 }
|
|
114
|
|
115
|
|
116 void ms_fifo_update_write_ptr(MSFifo *fifo, gint written){
|
|
117 gint reserved=fifo->wr_ptr-fifo->prev_wr_ptr;
|
|
118 gint unwritten;
|
|
119 g_return_if_fail(reserved>=0);
|
|
120 unwritten=reserved-written;
|
|
121 g_return_if_fail(unwritten>=0);
|
|
122 /* fix readsize and writesize */
|
|
123 fifo->readsize-=unwritten;
|
|
124 fifo->writesize+=unwritten;
|
|
125 fifo->wr_ptr+=written;
|
|
126 }
|
|
127
|
|
128 gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
|
|
129 {
|
|
130 gchar *wnext;
|
|
131
|
|
132 *ret_ptr=NULL;
|
|
133 //ms_trace("ms_fifo_get_write_ptr: Entering.");
|
|
134 g_return_val_if_fail(bsize<=fifo->w_gran,-EINVAL);
|
|
135 if (bsize>fifo->writesize)
|
|
136 {
|
|
137 ms_trace("Not enough space: bsize=%i, writesize=%i",bsize,fifo->writesize);
|
|
138 *ret_ptr=NULL;
|
|
139 return(-ENODATA);
|
|
140 }
|
|
141 wnext=fifo->wr_ptr+bsize;
|
|
142 if (wnext<=fifo->w_end){
|
|
143 *ret_ptr=fifo->wr_ptr;
|
|
144 fifo->wr_ptr=wnext;
|
|
145 }else{
|
|
146 *ret_ptr=fifo->begin;
|
|
147 fifo->r_end=fifo->wr_ptr;
|
|
148 fifo->wr_ptr=fifo->begin+bsize;
|
|
149 ms_trace("moving write ptr to %x",fifo->wr_ptr);
|
|
150 }
|
|
151 fifo->prev_wr_ptr=*ret_ptr;
|
|
152 /* update readsize*/
|
|
153 fifo->readsize+=bsize;
|
|
154 fifo->writesize-=bsize;
|
|
155 //ms_trace("ms_fifo_get_write_ptr: readsize=%i, writesize=%i",fifo->readsize,fifo->writesize);
|
|
156 return bsize;
|
|
157 }
|
|
158
|
|
159 gint ms_fifo_get_rw_ptr(MSFifo *f1,void **p1,gint minsize1,
|
|
160 MSFifo *f2,void **p2,gint minsize2)
|
|
161 {
|
|
162 gint rbsize,wbsize;
|
|
163
|
|
164 rbsize=MIN(f1->readsize,(f1->pre_end-f1->rd_ptr));
|
|
165 wbsize=MIN(f2->writesize,(f2->w_end-f2->wr_ptr));
|
|
166 return 0;
|
|
167 }
|