gst_plugins_base/gst/audioresample/buffer.c
changeset 2 5505e8908944
equal deleted inserted replaced
1:4c282e7dd6d3 2:5505e8908944
       
     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 #ifdef __SYMBIAN32__
       
    17 EXPORT_C
       
    18 #endif
       
    19 
       
    20 
       
    21 
       
    22 AudioresampleBuffer *
       
    23 audioresample_buffer_new (void)
       
    24 {
       
    25   AudioresampleBuffer *buffer;
       
    26 
       
    27   buffer = g_new0 (AudioresampleBuffer, 1);
       
    28   buffer->ref_count = 1;
       
    29   return buffer;
       
    30 }
       
    31 #ifdef __SYMBIAN32__
       
    32 EXPORT_C
       
    33 #endif
       
    34 
       
    35 
       
    36 AudioresampleBuffer *
       
    37 audioresample_buffer_new_and_alloc (int size)
       
    38 {
       
    39   AudioresampleBuffer *buffer = audioresample_buffer_new ();
       
    40 
       
    41   buffer->data = g_malloc (size);
       
    42   buffer->length = size;
       
    43   buffer->free = audioresample_buffer_free_mem;
       
    44 
       
    45   return buffer;
       
    46 }
       
    47 #ifdef __SYMBIAN32__
       
    48 EXPORT_C
       
    49 #endif
       
    50 
       
    51 
       
    52 AudioresampleBuffer *
       
    53 audioresample_buffer_new_with_data (void *data, int size)
       
    54 {
       
    55   AudioresampleBuffer *buffer = audioresample_buffer_new ();
       
    56 
       
    57   buffer->data = data;
       
    58   buffer->length = size;
       
    59   buffer->free = audioresample_buffer_free_mem;
       
    60 
       
    61   return buffer;
       
    62 }
       
    63 #ifdef __SYMBIAN32__
       
    64 EXPORT_C
       
    65 #endif
       
    66 
       
    67 
       
    68 AudioresampleBuffer *
       
    69 audioresample_buffer_new_subbuffer (AudioresampleBuffer * buffer, int offset,
       
    70     int length)
       
    71 {
       
    72   AudioresampleBuffer *subbuffer = audioresample_buffer_new ();
       
    73 
       
    74   if (buffer->parent) {
       
    75     audioresample_buffer_ref (buffer->parent);
       
    76     subbuffer->parent = buffer->parent;
       
    77   } else {
       
    78     audioresample_buffer_ref (buffer);
       
    79     subbuffer->parent = buffer;
       
    80   }
       
    81   subbuffer->data = buffer->data + offset;
       
    82   subbuffer->length = length;
       
    83   subbuffer->free = audioresample_buffer_free_subbuffer;
       
    84 
       
    85   return subbuffer;
       
    86 }
       
    87 #ifdef __SYMBIAN32__
       
    88 EXPORT_C
       
    89 #endif
       
    90 
       
    91 
       
    92 void
       
    93 audioresample_buffer_ref (AudioresampleBuffer * buffer)
       
    94 {
       
    95   buffer->ref_count++;
       
    96 }
       
    97 #ifdef __SYMBIAN32__
       
    98 EXPORT_C
       
    99 #endif
       
   100 
       
   101 
       
   102 void
       
   103 audioresample_buffer_unref (AudioresampleBuffer * buffer)
       
   104 {
       
   105   buffer->ref_count--;
       
   106   if (buffer->ref_count == 0) {
       
   107     if (buffer->free)
       
   108       buffer->free (buffer, buffer->priv);
       
   109     g_free (buffer);
       
   110   }
       
   111 }
       
   112 
       
   113 static void
       
   114 audioresample_buffer_free_mem (AudioresampleBuffer * buffer, void *priv)
       
   115 {
       
   116   g_free (buffer->data);
       
   117 }
       
   118 
       
   119 static void
       
   120 audioresample_buffer_free_subbuffer (AudioresampleBuffer * buffer, void *priv)
       
   121 {
       
   122   audioresample_buffer_unref (buffer->parent);
       
   123 }
       
   124 #ifdef __SYMBIAN32__
       
   125 EXPORT_C
       
   126 #endif
       
   127 
       
   128 
       
   129 
       
   130 AudioresampleBufferQueue *
       
   131 audioresample_buffer_queue_new (void)
       
   132 {
       
   133   return g_new0 (AudioresampleBufferQueue, 1);
       
   134 }
       
   135 #ifdef __SYMBIAN32__
       
   136 EXPORT_C
       
   137 #endif
       
   138 
       
   139 
       
   140 int
       
   141 audioresample_buffer_queue_get_depth (AudioresampleBufferQueue * queue)
       
   142 {
       
   143   return queue->depth;
       
   144 }
       
   145 #ifdef __SYMBIAN32__
       
   146 EXPORT_C
       
   147 #endif
       
   148 
       
   149 
       
   150 int
       
   151 audioresample_buffer_queue_get_offset (AudioresampleBufferQueue * queue)
       
   152 {
       
   153   return queue->offset;
       
   154 }
       
   155 #ifdef __SYMBIAN32__
       
   156 EXPORT_C
       
   157 #endif
       
   158 
       
   159 
       
   160 void
       
   161 audioresample_buffer_queue_free (AudioresampleBufferQueue * queue)
       
   162 {
       
   163   GList *g;
       
   164 
       
   165   for (g = g_list_first (queue->buffers); g; g = g_list_next (g)) {
       
   166     audioresample_buffer_unref ((AudioresampleBuffer *) g->data);
       
   167   }
       
   168   g_list_free (queue->buffers);
       
   169   g_free (queue);
       
   170 }
       
   171 #ifdef __SYMBIAN32__
       
   172 EXPORT_C
       
   173 #endif
       
   174 
       
   175 
       
   176 void
       
   177 audioresample_buffer_queue_push (AudioresampleBufferQueue * queue,
       
   178     AudioresampleBuffer * buffer)
       
   179 {
       
   180   queue->buffers = g_list_append (queue->buffers, buffer);
       
   181   queue->depth += buffer->length;
       
   182 }
       
   183 #ifdef __SYMBIAN32__
       
   184 EXPORT_C
       
   185 #endif
       
   186 
       
   187 
       
   188 AudioresampleBuffer *
       
   189 audioresample_buffer_queue_pull (AudioresampleBufferQueue * queue, int length)
       
   190 {
       
   191   GList *g;
       
   192   AudioresampleBuffer *newbuffer;
       
   193   AudioresampleBuffer *buffer;
       
   194   AudioresampleBuffer *subbuffer;
       
   195 
       
   196   g_return_val_if_fail (length > 0, NULL);
       
   197 
       
   198   if (queue->depth < length) {
       
   199     return NULL;
       
   200   }
       
   201 
       
   202   RESAMPLE_LOG ("pulling %d, %d available", length, queue->depth);
       
   203 
       
   204   g = g_list_first (queue->buffers);
       
   205   buffer = g->data;
       
   206 
       
   207   if (buffer->length > length) {
       
   208     newbuffer = audioresample_buffer_new_subbuffer (buffer, 0, length);
       
   209 
       
   210     subbuffer = audioresample_buffer_new_subbuffer (buffer, length,
       
   211         buffer->length - length);
       
   212     g->data = subbuffer;
       
   213     audioresample_buffer_unref (buffer);
       
   214   } else {
       
   215     int offset = 0;
       
   216 
       
   217     newbuffer = audioresample_buffer_new_and_alloc (length);
       
   218 
       
   219     while (offset < length) {
       
   220       g = g_list_first (queue->buffers);
       
   221       buffer = g->data;
       
   222 
       
   223       if (buffer->length > length - offset) {
       
   224         int n = length - offset;
       
   225 
       
   226         memcpy (newbuffer->data + offset, buffer->data, n);
       
   227         subbuffer =
       
   228             audioresample_buffer_new_subbuffer (buffer, n, buffer->length - n);
       
   229         g->data = subbuffer;
       
   230         audioresample_buffer_unref (buffer);
       
   231         offset += n;
       
   232       } else {
       
   233         memcpy (newbuffer->data + offset, buffer->data, buffer->length);
       
   234 
       
   235         queue->buffers = g_list_delete_link (queue->buffers, g);
       
   236         offset += buffer->length;
       
   237         audioresample_buffer_unref (buffer);
       
   238       }
       
   239     }
       
   240   }
       
   241 
       
   242   queue->depth -= length;
       
   243   queue->offset += length;
       
   244 
       
   245   return newbuffer;
       
   246 }
       
   247 #ifdef __SYMBIAN32__
       
   248 EXPORT_C
       
   249 #endif
       
   250 
       
   251 
       
   252 AudioresampleBuffer *
       
   253 audioresample_buffer_queue_peek (AudioresampleBufferQueue * queue, int length)
       
   254 {
       
   255   GList *g;
       
   256   AudioresampleBuffer *newbuffer;
       
   257   AudioresampleBuffer *buffer;
       
   258   int offset = 0;
       
   259 
       
   260   g_return_val_if_fail (length > 0, NULL);
       
   261 
       
   262   if (queue->depth < length) {
       
   263     return NULL;
       
   264   }
       
   265 
       
   266   RESAMPLE_LOG ("peeking %d, %d available", length, queue->depth);
       
   267 
       
   268   g = g_list_first (queue->buffers);
       
   269   buffer = g->data;
       
   270   if (buffer->length > length) {
       
   271     newbuffer = audioresample_buffer_new_subbuffer (buffer, 0, length);
       
   272   } else {
       
   273     newbuffer = audioresample_buffer_new_and_alloc (length);
       
   274     while (offset < length) {
       
   275       buffer = g->data;
       
   276 
       
   277       if (buffer->length > length - offset) {
       
   278         int n = length - offset;
       
   279 
       
   280         memcpy (newbuffer->data + offset, buffer->data, n);
       
   281         offset += n;
       
   282       } else {
       
   283         memcpy (newbuffer->data + offset, buffer->data, buffer->length);
       
   284         offset += buffer->length;
       
   285       }
       
   286       g = g_list_next (g);
       
   287     }
       
   288   }
       
   289 
       
   290   return newbuffer;
       
   291 }
       
   292 #ifdef __SYMBIAN32__
       
   293 EXPORT_C
       
   294 #endif
       
   295 
       
   296 
       
   297 void
       
   298 audioresample_buffer_queue_flush (AudioresampleBufferQueue * queue)
       
   299 {
       
   300   GList *g;
       
   301 
       
   302   for (g = g_list_first (queue->buffers); g; g = g_list_next (g)) {
       
   303     audioresample_buffer_unref ((AudioresampleBuffer *) g->data);
       
   304   }
       
   305   g_list_free (queue->buffers);
       
   306   queue->buffers = NULL;
       
   307   queue->depth = 0;
       
   308   queue->offset = 0;
       
   309 }