Add some more debugging to the Xv strides
[platform/upstream/gstreamer.git] / gst / audioresample / buffer.c
1
2 #ifndef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include <glib.h>
7 #include <string.h>
8
9 #include "buffer.h"
10 #include "debug.h"
11
12 static void audioresample_buffer_free_mem (AudioresampleBuffer * buffer,
13     void *);
14 static void audioresample_buffer_free_subbuffer (AudioresampleBuffer * buffer,
15     void *priv);
16
17
18 AudioresampleBuffer *
19 audioresample_buffer_new (void)
20 {
21   AudioresampleBuffer *buffer;
22
23   buffer = g_new0 (AudioresampleBuffer, 1);
24   buffer->ref_count = 1;
25   return buffer;
26 }
27
28 AudioresampleBuffer *
29 audioresample_buffer_new_and_alloc (int size)
30 {
31   AudioresampleBuffer *buffer = audioresample_buffer_new ();
32
33   buffer->data = g_malloc (size);
34   buffer->length = size;
35   buffer->free = audioresample_buffer_free_mem;
36
37   return buffer;
38 }
39
40 AudioresampleBuffer *
41 audioresample_buffer_new_with_data (void *data, int size)
42 {
43   AudioresampleBuffer *buffer = audioresample_buffer_new ();
44
45   buffer->data = data;
46   buffer->length = size;
47   buffer->free = audioresample_buffer_free_mem;
48
49   return buffer;
50 }
51
52 AudioresampleBuffer *
53 audioresample_buffer_new_subbuffer (AudioresampleBuffer * buffer, int offset,
54     int length)
55 {
56   AudioresampleBuffer *subbuffer = audioresample_buffer_new ();
57
58   if (buffer->parent) {
59     audioresample_buffer_ref (buffer->parent);
60     subbuffer->parent = buffer->parent;
61   } else {
62     audioresample_buffer_ref (buffer);
63     subbuffer->parent = buffer;
64   }
65   subbuffer->data = buffer->data + offset;
66   subbuffer->length = length;
67   subbuffer->free = audioresample_buffer_free_subbuffer;
68
69   return subbuffer;
70 }
71
72 void
73 audioresample_buffer_ref (AudioresampleBuffer * buffer)
74 {
75   buffer->ref_count++;
76 }
77
78 void
79 audioresample_buffer_unref (AudioresampleBuffer * buffer)
80 {
81   buffer->ref_count--;
82   if (buffer->ref_count == 0) {
83     if (buffer->free)
84       buffer->free (buffer, buffer->priv);
85     g_free (buffer);
86   }
87 }
88
89 static void
90 audioresample_buffer_free_mem (AudioresampleBuffer * buffer, void *priv)
91 {
92   g_free (buffer->data);
93 }
94
95 static void
96 audioresample_buffer_free_subbuffer (AudioresampleBuffer * buffer, void *priv)
97 {
98   audioresample_buffer_unref (buffer->parent);
99 }
100
101
102 AudioresampleBufferQueue *
103 audioresample_buffer_queue_new (void)
104 {
105   return g_new0 (AudioresampleBufferQueue, 1);
106 }
107
108 int
109 audioresample_buffer_queue_get_depth (AudioresampleBufferQueue * queue)
110 {
111   return queue->depth;
112 }
113
114 int
115 audioresample_buffer_queue_get_offset (AudioresampleBufferQueue * queue)
116 {
117   return queue->offset;
118 }
119
120 void
121 audioresample_buffer_queue_free (AudioresampleBufferQueue * queue)
122 {
123   GList *g;
124
125   for (g = g_list_first (queue->buffers); g; g = g_list_next (g)) {
126     audioresample_buffer_unref ((AudioresampleBuffer *) g->data);
127   }
128   g_list_free (queue->buffers);
129   g_free (queue);
130 }
131
132 void
133 audioresample_buffer_queue_push (AudioresampleBufferQueue * queue,
134     AudioresampleBuffer * buffer)
135 {
136   queue->buffers = g_list_append (queue->buffers, buffer);
137   queue->depth += buffer->length;
138 }
139
140 AudioresampleBuffer *
141 audioresample_buffer_queue_pull (AudioresampleBufferQueue * queue, int length)
142 {
143   GList *g;
144   AudioresampleBuffer *newbuffer;
145   AudioresampleBuffer *buffer;
146   AudioresampleBuffer *subbuffer;
147
148   g_return_val_if_fail (length > 0, NULL);
149
150   if (queue->depth < length) {
151     return NULL;
152   }
153
154   RESAMPLE_LOG ("pulling %d, %d available", length, queue->depth);
155
156   g = g_list_first (queue->buffers);
157   buffer = g->data;
158
159   if (buffer->length > length) {
160     newbuffer = audioresample_buffer_new_subbuffer (buffer, 0, length);
161
162     subbuffer = audioresample_buffer_new_subbuffer (buffer, length,
163         buffer->length - length);
164     g->data = subbuffer;
165     audioresample_buffer_unref (buffer);
166   } else {
167     int offset = 0;
168
169     newbuffer = audioresample_buffer_new_and_alloc (length);
170
171     while (offset < length) {
172       g = g_list_first (queue->buffers);
173       buffer = g->data;
174
175       if (buffer->length > length - offset) {
176         int n = length - offset;
177
178         memcpy (newbuffer->data + offset, buffer->data, n);
179         subbuffer =
180             audioresample_buffer_new_subbuffer (buffer, n, buffer->length - n);
181         g->data = subbuffer;
182         audioresample_buffer_unref (buffer);
183         offset += n;
184       } else {
185         memcpy (newbuffer->data + offset, buffer->data, buffer->length);
186
187         queue->buffers = g_list_delete_link (queue->buffers, g);
188         offset += buffer->length;
189         audioresample_buffer_unref (buffer);
190       }
191     }
192   }
193
194   queue->depth -= length;
195   queue->offset += length;
196
197   return newbuffer;
198 }
199
200 AudioresampleBuffer *
201 audioresample_buffer_queue_peek (AudioresampleBufferQueue * queue, int length)
202 {
203   GList *g;
204   AudioresampleBuffer *newbuffer;
205   AudioresampleBuffer *buffer;
206   int offset = 0;
207
208   g_return_val_if_fail (length > 0, NULL);
209
210   if (queue->depth < length) {
211     return NULL;
212   }
213
214   RESAMPLE_LOG ("peeking %d, %d available", length, queue->depth);
215
216   g = g_list_first (queue->buffers);
217   buffer = g->data;
218   if (buffer->length > length) {
219     newbuffer = audioresample_buffer_new_subbuffer (buffer, 0, length);
220   } else {
221     newbuffer = audioresample_buffer_new_and_alloc (length);
222     while (offset < length) {
223       buffer = g->data;
224
225       if (buffer->length > length - offset) {
226         int n = length - offset;
227
228         memcpy (newbuffer->data + offset, buffer->data, n);
229         offset += n;
230       } else {
231         memcpy (newbuffer->data + offset, buffer->data, buffer->length);
232         offset += buffer->length;
233       }
234       g = g_list_next (g);
235     }
236   }
237
238   return newbuffer;
239 }
240
241 void
242 audioresample_buffer_queue_flush (AudioresampleBufferQueue * queue)
243 {
244   GList *g;
245
246   for (g = g_list_first (queue->buffers); g; g = g_list_next (g)) {
247     audioresample_buffer_unref ((AudioresampleBuffer *) g->data);
248   }
249   g_list_free (queue->buffers);
250   queue->buffers = NULL;
251   queue->depth = 0;
252   queue->offset = 0;
253 }