diff options
author | David Schleef <ds@schleef.org> | 2005-05-17 07:11:56 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2005-05-17 07:11:56 +0000 |
commit | 9bc18a9a15e8ea20bf3fde066294b2866b751f6f (patch) | |
tree | 74e9875d5a45976fb5e7b4c6ef7ad1b651979949 /gst/librfb/rfbbuffer.c | |
parent | 1be79923f04722ba0cd3538bc9d80a2c5c509910 (diff) | |
download | gst-plugins-bad-9bc18a9a15e8ea20bf3fde066294b2866b751f6f.tar.gz gst-plugins-bad-9bc18a9a15e8ea20bf3fde066294b2866b751f6f.tar.bz2 gst-plugins-bad-9bc18a9a15e8ea20bf3fde066294b2866b751f6f.zip |
gst/librfb/: Some much needed hackage. Fixed #171659, but then went on to actually make it work with Vino, get timin...
Original commit message from CVS:
* gst/librfb/Makefile.am:
* gst/librfb/gstrfbsrc.c:
* gst/librfb/rfb.h:
* gst/librfb/rfbbuffer.c:
* gst/librfb/rfbbuffer.h:
* gst/librfb/rfbbytestream.c:
* gst/librfb/rfbbytestream.h:
* gst/librfb/rfbdecoder.c:
* gst/librfb/rfbdecoder.h:
Some much needed hackage. Fixed #171659, but then went on
to actually make it work with Vino, get timing correct,
make sure it doesn't leak, etc.
Diffstat (limited to 'gst/librfb/rfbbuffer.c')
-rw-r--r-- | gst/librfb/rfbbuffer.c | 220 |
1 files changed, 213 insertions, 7 deletions
diff --git a/gst/librfb/rfbbuffer.c b/gst/librfb/rfbbuffer.c index e38def36..7b9c3c47 100644 --- a/gst/librfb/rfbbuffer.c +++ b/gst/librfb/rfbbuffer.c @@ -1,27 +1,233 @@ +#ifndef HAVE_CONFIG_H +#include "config.h" +#endif + #include <rfbbuffer.h> +#include <glib.h> +#include <string.h> +#include <gst/gst.h> + +static void rfb_buffer_free_mem (RfbBuffer * buffer, void *); +static void rfb_buffer_free_subbuffer (RfbBuffer * buffer, void *priv); + +#define oil_copy_u8(a,b,c) memcpy(a,b,c) RfbBuffer * rfb_buffer_new (void) { - return g_new0 (RfbBuffer, 1); + RfbBuffer *buffer; + buffer = g_new0 (RfbBuffer, 1); + buffer->ref_count = 1; + return buffer; } RfbBuffer * -rfb_buffer_new_and_alloc (int len) +rfb_buffer_new_and_alloc (int size) { - RfbBuffer *buffer = g_new0 (RfbBuffer, 1); + RfbBuffer *buffer = rfb_buffer_new (); - buffer->data = g_malloc (len); - buffer->free_data = (void *) g_free; + buffer->data = g_malloc (size); + buffer->length = size; + buffer->free = rfb_buffer_free_mem; return buffer; } +RfbBuffer * +rfb_buffer_new_with_data (void *data, int size) +{ + RfbBuffer *buffer = rfb_buffer_new (); + + buffer->data = data; + buffer->length = size; + buffer->free = rfb_buffer_free_mem; + + return buffer; +} + +RfbBuffer * +rfb_buffer_new_subbuffer (RfbBuffer * buffer, int offset, int length) +{ + RfbBuffer *subbuffer = rfb_buffer_new (); + + if (buffer->parent) { + rfb_buffer_ref (buffer->parent); + subbuffer->parent = buffer->parent; + } else { + rfb_buffer_ref (buffer); + subbuffer->parent = buffer; + } + subbuffer->data = buffer->data + offset; + subbuffer->length = length; + subbuffer->free = rfb_buffer_free_subbuffer; + + return subbuffer; +} + void -rfb_buffer_free (RfbBuffer * buffer) +rfb_buffer_ref (RfbBuffer * buffer) +{ + buffer->ref_count++; +} + +void +rfb_buffer_unref (RfbBuffer * buffer) +{ + buffer->ref_count--; + if (buffer->ref_count == 0) { + if (buffer->free) + buffer->free (buffer, buffer->priv); + g_free (buffer); + } +} + +static void +rfb_buffer_free_mem (RfbBuffer * buffer, void *priv) +{ + g_free (buffer->data); +} + +static void +rfb_buffer_free_subbuffer (RfbBuffer * buffer, void *priv) +{ + rfb_buffer_unref (buffer->parent); +} + + +RfbBufferQueue * +rfb_buffer_queue_new (void) +{ + return g_new0 (RfbBufferQueue, 1); +} + +int +rfb_buffer_queue_get_depth (RfbBufferQueue * queue) +{ + return queue->depth; +} + +int +rfb_buffer_queue_get_offset (RfbBufferQueue * queue) { - buffer->free_data (buffer->data, buffer->buffer_private); + return queue->offset; +} + +void +rfb_buffer_queue_free (RfbBufferQueue * queue) +{ + GList *g; + + for (g = g_list_first (queue->buffers); g; g = g_list_next (g)) { + rfb_buffer_unref ((RfbBuffer *) g->data); + } + g_list_free (queue->buffers); + g_free (queue); +} + +void +rfb_buffer_queue_push (RfbBufferQueue * queue, RfbBuffer * buffer) +{ + queue->buffers = g_list_append (queue->buffers, buffer); + queue->depth += buffer->length; +} + +RfbBuffer * +rfb_buffer_queue_pull (RfbBufferQueue * queue, int length) +{ + GList *g; + RfbBuffer *newbuffer; + RfbBuffer *buffer; + RfbBuffer *subbuffer; + + g_return_val_if_fail (length > 0, NULL); + + if (queue->depth < length) { + return NULL; + } + + GST_LOG ("pulling %d, %d available", length, queue->depth); + + g = g_list_first (queue->buffers); + buffer = g->data; + + if (buffer->length > length) { + newbuffer = rfb_buffer_new_subbuffer (buffer, 0, length); + + subbuffer = rfb_buffer_new_subbuffer (buffer, length, + buffer->length - length); + g->data = subbuffer; + rfb_buffer_unref (buffer); + } else { + int offset = 0; + + newbuffer = rfb_buffer_new_and_alloc (length); + + while (offset < length) { + g = g_list_first (queue->buffers); + buffer = g->data; + + if (buffer->length > length - offset) { + int n = length - offset; + + oil_copy_u8 (newbuffer->data + offset, buffer->data, n); + subbuffer = rfb_buffer_new_subbuffer (buffer, n, buffer->length - n); + g->data = subbuffer; + rfb_buffer_unref (buffer); + offset += n; + } else { + oil_copy_u8 (newbuffer->data + offset, buffer->data, buffer->length); + + queue->buffers = g_list_delete_link (queue->buffers, g); + offset += buffer->length; + } + } + } + + queue->depth -= length; + queue->offset += length; + + return newbuffer; +} + +RfbBuffer * +rfb_buffer_queue_peek (RfbBufferQueue * queue, int length) +{ + GList *g; + RfbBuffer *newbuffer; + RfbBuffer *buffer; + int offset = 0; + + g_return_val_if_fail (length > 0, NULL); + + if (queue->depth < length) { + return NULL; + } + + GST_LOG ("peeking %d, %d available", length, queue->depth); + + g = g_list_first (queue->buffers); + buffer = g->data; + if (buffer->length > length) { + newbuffer = rfb_buffer_new_subbuffer (buffer, 0, length); + } else { + newbuffer = rfb_buffer_new_and_alloc (length); + while (offset < length) { + buffer = g->data; + + if (buffer->length > length - offset) { + int n = length - offset; + + oil_copy_u8 (newbuffer->data + offset, buffer->data, n); + offset += n; + } else { + oil_copy_u8 (newbuffer->data + offset, buffer->data, buffer->length); + offset += buffer->length; + } + g = g_list_next (g); + } + } + return newbuffer; } |