[xiph-commits] r2991 - liboggplay/trunk/src/liboggplay
shans at svn.annodex.net
shans at svn.annodex.net
Mon Jun 18 08:06:04 PDT 2007
Author: shans
Date: 2007-06-18 08:06:04 -0700 (Mon, 18 Jun 2007)
New Revision: 2991
Modified:
liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.c
liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.h
Log:
Added a backing file store for oggplay objects, via the tmpfile() function call.
This ensures that we don't fill up memory with saved video.
Modified: liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.c 2007-06-18 10:43:05 UTC (rev 2990)
+++ liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.c 2007-06-18 15:06:04 UTC (rev 2991)
@@ -65,7 +65,12 @@
#define INVALID_SOCKET -1
#endif
+#define PRINT_BUFFER(s,m) \
+ printf("%s: in_mem: %d size: %d pos: %d stored: %d\n", \
+ s, m->amount_in_memory, m->buffer_size, \
+ m->current_position, m->stored_offset);
+
static int
set_socket_blocking_state(OggPlayTCPReader *me, int is_blocking) {
#ifdef WIN32
@@ -293,18 +298,20 @@
int offset;
if (me->buffer == NULL) {
- me->buffer = (unsigned char*)malloc(TCP_READER_MAX_BUFFER_SIZE);
- me->buffer_size = 0;
- printf("creating buffer at %p, 0 filled\n", me->buffer);
+ me->buffer = (unsigned char*)malloc(TCP_READER_MAX_IN_MEMORY);
+ me->buffer_size = TCP_READER_MAX_IN_MEMORY;
+ me->amount_in_memory = 0;
}
START_TIMEOUT(time_ref);
while (1) {
- remaining = TCP_READER_MAX_BUFFER_SIZE - me->buffer_size;
+ remaining = TCP_READER_MAX_IN_MEMORY - me->amount_in_memory;
#ifdef WIN32
- nbytes = recv(me->socket, (char*)(me->buffer + me->buffer_size), remaining - 1, 0);
+ nbytes = recv(me->socket, (char*)(me->buffer + me->amount_in_memory),
+ remaining - 1, 0);
#else
- nbytes = read(me->socket, (char*)(me->buffer + me->buffer_size), remaining - 1);
+ nbytes = read(me->socket, (char*)(me->buffer + me->amount_in_memory),
+ remaining - 1);
#endif
if (nbytes < 0) {
#ifdef WIN32
@@ -322,7 +329,7 @@
*/
return E_OGGPLAY_END_OF_FILE;
}
- me->buffer[me->buffer_size + nbytes] = '\0';
+ me->buffer[me->amount_in_memory + nbytes] = '\0';
pos = strstr((char *)(me->buffer), "OggS");
if (pos != NULL) {
break;
@@ -334,31 +341,32 @@
}
if (nbytes > 4) {
memmove(me->buffer, me->buffer + nbytes - 4, 4);
- me->buffer_size = 4;
+ me->amount_in_memory = 4;
} else {
- me->buffer_size = nbytes;
+ me->amount_in_memory = nbytes;
}
}
offset = pos - (char *)(me->buffer);
memmove(me->buffer, pos, nbytes - offset);
- me->buffer_size = nbytes - offset;
+ me->amount_in_memory = nbytes - offset;
+ me->stored_offset = 0;
me->state = OTRS_HTTP_RESPONDED;
}
- printf("OggS packet found, buffer now: %d@%p\n", me->buffer_size, me->buffer);
/*
* Read in enough data to fill the buffer.
*/
if (me->state == OTRS_HTTP_RESPONDED) {
- remaining = TCP_READER_MAX_BUFFER_SIZE - me->buffer_size;
+ remaining = TCP_READER_MAX_IN_MEMORY - me->amount_in_memory;
START_TIMEOUT(time_ref);
while (remaining > 0) {
#ifdef WIN32
- nbytes = recv(me->socket, (char*)(me->buffer + me->buffer_size), remaining, 0);
+ nbytes = recv(me->socket, (char*)(me->buffer + me->amount_in_memory),
+ remaining, 0);
#else
- nbytes = read(me->socket, me->buffer + me->buffer_size, remaining);
+ nbytes = read(me->socket, me->buffer + me->amount_in_memory, remaining);
#endif
if (nbytes < 0) {
#ifdef WIN32
@@ -375,13 +383,13 @@
*/
break;
}
- me->buffer_size += nbytes;
+ me->amount_in_memory += nbytes;
remaining -= nbytes;
}
me->state = OTRS_INIT_COMPLETE;
}
- printf("filled, buffer now: %d@%p\n", me->buffer_size, me->buffer);
+ me->backing_store = NULL;
/*
* Set the socket back to blocking mode.
@@ -412,18 +420,26 @@
}
free(me->buffer);
+ if (me->backing_store != NULL) {
+ fclose(me->backing_store);
+ }
free(me);
return E_OGGPLAY_OK;
}
-
OggPlayErrorCode
grab_some_data(OggPlayTCPReader *me, int block) {
int remaining;
int r;
- printf("grab_some_data %s\n", block ? "and block" : "if available");
+ /*
+ * woah, too much stuff in memory already and we're just speculatively
+ * retrieving the data. How about we don't bother.
+ */
+ if (me->amount_in_memory == TCP_READER_MAX_IN_MEMORY && !block) {
+ goto clean_data_out;
+ }
/*
* see if we can grab some more data
@@ -443,14 +459,13 @@
return E_OGGPLAY_OK;
}
}
- me->buffer = realloc(me->buffer,
- TCP_READER_MAX_BUFFER_SIZE + me->buffer_size);
- printf("buffer realloced to %p, size %d\n", me->buffer, me->buffer_size);
- remaining = TCP_READER_MAX_BUFFER_SIZE;
+
+ remaining = me->buffer_size - me->amount_in_memory;
#ifdef WIN32
- r = recv(me->socket, (char*)(me->buffer + me->buffer_size), remaining, 0);
+ r = recv(me->socket, (char*)(me->buffer + me->amount_in_memory),
+ remaining, 0);
#else
- r = read(me->socket, me->buffer + me->buffer_size, remaining);
+ r = read(me->socket, me->buffer + me->amount_in_memory, remaining);
#endif
if (r < 0) {
return E_OGGPLAY_SOCKET_ERROR;
@@ -458,9 +473,78 @@
return E_OGGPLAY_END_OF_FILE;
}
- me->buffer_size += r;
- printf("buffer now %p, size %d\n", me->buffer, me->buffer_size);
+ me->amount_in_memory += r;
+clean_data_out:
+
+ if (me->amount_in_memory > TCP_READER_WRITE_THRESHOLD) {
+
+ int can_write;
+
+ /*
+ * we're going to try and dump some of this data on disk.
+ * Note that we might not actually be able to open a backing store. If
+ * we can't then we just continue in memory
+ */
+ if (me->backing_store == NULL) {
+ me->backing_store = tmpfile();
+ //me->backing_store = fopen("temp.ogg", "w");
+ if (me->backing_store == NULL) {
+ me->buffer_size *= 2;
+ me->buffer = realloc(me->buffer, me->buffer_size);
+ return E_OGGPLAY_OK;
+ }
+ }
+
+ /*
+ * So amount_in_memory is our currently resident amount, and we've used
+ * up to position.
+ *
+ * position
+ * v
+ * |<---amount_in_memory-->]
+ *
+ * So the amount we COULD write is me->position.
+ */
+
+ can_write = me->current_position;
+
+ /*
+ * BUT we don't really want to write more than we have to, so lets
+ * leave TCP_READER_WRITE_THRESHOLD behind
+ */
+
+ if (me->amount_in_memory - can_write < TCP_READER_WRITE_THRESHOLD) {
+ can_write = me->amount_in_memory - TCP_READER_WRITE_THRESHOLD;
+ }
+
+ /*
+ * although, if we aren't writing anything to disk, why are we here?
+ */
+ if (can_write == 0) {
+ return E_OGGPLAY_OK;
+ }
+
+ /*
+ * OK Joe, flush it outa heeeeere!
+ */
+ fwrite(me->buffer, can_write, 1, me->backing_store);
+
+ /*
+ * now we need to pull everything back to the beginning of the buffer
+ */
+ memmove(me->buffer, me->buffer + can_write,
+ me->amount_in_memory - can_write);
+ me->amount_in_memory -= can_write;
+ me->current_position -= can_write;
+
+ /*
+ * finally, fix the offset
+ */
+ me->stored_offset += can_write;
+
+ }
+
return E_OGGPLAY_OK;
}
@@ -470,7 +554,6 @@
unsigned char ** position, int * size, int * base) {
OggPlayTCPReader * me = (OggPlayTCPReader *)opr;
- int old_buffer_size = me->buffer_size;
/*
* check for end of file condition
@@ -482,8 +565,8 @@
grab_some_data(me, 0);
*position = me->buffer + me->current_position;
- *size = me->buffer_size - me->current_position;
-
+ *size = me->amount_in_memory - me->current_position;
+
/*
* last chunk
*/
@@ -491,14 +574,14 @@
return E_OGGPLAY_OK;
}
- if (me->buffer_size == old_buffer_size) {
+ if (me->amount_in_memory - me->current_position == 0) {
grab_some_data(me, 1);
*position = me->buffer + me->current_position;
- *size = me->buffer_size - me->current_position;
+ *size = me->amount_in_memory - me->current_position;
}
+ *base = me->stored_offset + me->current_position;
me->current_position += *size;
- *base = me->current_position;
return E_OGGPLAY_OK;
}
Modified: liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.h
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.h 2007-06-18 10:43:05 UTC (rev 2990)
+++ liboggplay/trunk/src/liboggplay/oggplay_tcp_reader.h 2007-06-18 15:06:04 UTC (rev 2991)
@@ -42,7 +42,11 @@
#include <stdio.h>
-#define TCP_READER_MAX_BUFFER_SIZE 16384
+/* we'll fill to the MAX_IN_MEMORY line, then write out to the
+ * WRITE_THRESHOLD line
+ */
+#define TCP_READER_MAX_IN_MEMORY 128*1024
+#define TCP_READER_WRITE_THRESHOLD 64*1024
typedef enum {
OTRS_UNINITIALISED,
@@ -65,6 +69,9 @@
int buffer_size;
int current_position;
char * location;
+ int amount_in_memory;
+ FILE * backing_store;
+ int stored_offset;
} OggPlayTCPReader;
#endif
More information about the commits
mailing list