[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