[xiph-commits] r3293 - liboggz/trunk/src/liboggz

shans at svn.annodex.net shans at svn.annodex.net
Thu Dec 6 19:48:26 PST 2007


Author: shans
Date: 2007-12-06 19:48:25 -0800 (Thu, 06 Dec 2007)
New Revision: 3293

Modified:
   liboggz/trunk/src/liboggz/oggz_private.h
   liboggz/trunk/src/liboggz/oggz_write.c
Log:
Continue writing after last packet is encountered to ensure that the 
final page is flushed to libogg and written to the file (changes made to 
both oggz_write and oggz_write_output but only oggz_write tested)



Modified: liboggz/trunk/src/liboggz/oggz_private.h
===================================================================
--- liboggz/trunk/src/liboggz/oggz_private.h	2007-12-06 10:18:03 UTC (rev 3292)
+++ liboggz/trunk/src/liboggz/oggz_private.h	2007-12-07 03:48:25 UTC (rev 3293)
@@ -183,6 +183,10 @@
   int page_offset; /* n bytes already copied out of current page */
 
   ogg_stream_state * current_stream;
+
+  int no_more_packets; /* used only in the local oggz_write loop to indicate
+                          end of stream */
+
 };
 
 struct _OggzIO {

Modified: liboggz/trunk/src/liboggz/oggz_write.c
===================================================================
--- liboggz/trunk/src/liboggz/oggz_write.c	2007-12-06 10:18:03 UTC (rev 3292)
+++ liboggz/trunk/src/liboggz/oggz_write.c	2007-12-07 03:48:25 UTC (rev 3293)
@@ -103,6 +103,7 @@
   writer->hungry_only_when_empty = 0;
 
   writer->writing = 0;
+  writer->no_more_packets = 0;
   writer->state = OGGZ_MAKING_PACKETS;
 
   writer->flushing = 0;
@@ -635,11 +636,13 @@
 long
 oggz_write_output (OGGZ * oggz, unsigned char * buf, long n)
 {
-  OggzWriter * writer = &oggz->x.writer;
+  OggzWriter * writer;
   long bytes, bytes_written = 1, remaining = n, nwritten = 0;
   int active = 1, cb_ret = 0;
 
   if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
+ 
+  writer = &oggz->x.writer;
 
   if (!(oggz->flags & OGGZ_WRITE)) {
     return OGGZ_ERR_INVALID;
@@ -651,6 +654,7 @@
   if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
     oggz->cb_next = 0;
     writer->writing = 0;
+    writer->no_more_packets = 0;
     return oggz_map_return_value_to_error (cb_ret);
   }
 
@@ -659,11 +663,14 @@
 
     while (writer->state == OGGZ_MAKING_PACKETS) {
       if ((cb_ret = oggz_writer_make_packet (oggz)) != OGGZ_CONTINUE) {
-	active = 0;
-	break;
+        if (cb_ret == OGGZ_WRITE_EMPTY) {
+          writer->flushing = 1;
+          writer->no_more_packets = 1;
+          cb_ret = OGGZ_CONTINUE;
+        }
       }
       if (oggz_page_init (oggz)) {
-	writer->state = OGGZ_WRITING_PAGES;
+        writer->state = OGGZ_WRITING_PAGES;
       }
     }
 
@@ -671,12 +678,15 @@
       bytes_written = oggz_page_copyout (oggz, buf, bytes);
 
       if (bytes_written == -1) {
-	active = 0;
+        active = 0;
         cb_ret = OGGZ_ERR_SYSTEM; /* XXX: catch next */
       } else if (bytes_written == 0) {
-	if (!oggz_page_init (oggz)) {
-	  writer->state = OGGZ_MAKING_PACKETS;
-	}
+        if (writer->no_more_packets) {
+          active = 0;
+          break;
+        } else if (!oggz_page_init (oggz)) {
+          writer->state = OGGZ_MAKING_PACKETS;
+        }
       }
 
       buf += bytes_written;
@@ -701,12 +711,14 @@
 long
 oggz_write (OGGZ * oggz, long n)
 {
-  OggzWriter * writer = &oggz->x.writer;
+  OggzWriter * writer;
   long bytes, bytes_written = 1, remaining = n, nwritten = 0;
   int active = 1, cb_ret = 0;
 
   if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
 
+  writer = &oggz->x.writer;
+
   if (!(oggz->flags & OGGZ_WRITE)) {
     return OGGZ_ERR_INVALID;
   }
@@ -721,6 +733,7 @@
   if ((cb_ret = oggz->cb_next) != OGGZ_CONTINUE) {
     oggz->cb_next = 0;
     writer->writing = 0;
+    writer->no_more_packets = 0;
     if (cb_ret == OGGZ_WRITE_EMPTY) cb_ret = 0;
     return oggz_map_return_value_to_error (cb_ret);
   }
@@ -735,11 +748,22 @@
 
     while (writer->state == OGGZ_MAKING_PACKETS) {
       if ((cb_ret = oggz_writer_make_packet (oggz)) != OGGZ_CONTINUE) {
-	      active = 0;
 #ifdef DEBUG
       	printf ("oggz_write: no packets (cb_ret is %d)\n", cb_ret);
 #endif
-      	break;
+        /*
+         * if we're out of packets because we're at the end of the file,
+         * we can't finish just yet.  Instead we need to force a page flush,
+         * and write the page out.  So we set flushing and no_more_packets to
+         * 1.  This causes oggz_page_init to flush the page, then we 
+         * will switch the state to OGGZ_WRITING_PAGES, which will trigger
+         * the writing code below.
+         */
+        if (cb_ret == OGGZ_WRITE_EMPTY) {
+          writer->flushing = 1;
+          writer->no_more_packets = 1;
+          cb_ret = OGGZ_CONTINUE;
+        }
       }
       if (oggz_page_init (oggz)) {
         writer->state = OGGZ_WRITING_PAGES;
@@ -753,12 +777,21 @@
         active = 0;
         return OGGZ_ERR_SYSTEM; /* XXX: catch next */
       } else if (bytes_written == 0) {
-	if (!oggz_page_init (oggz)) {
+        /*
+         * OK so we've completely written the current page.  If no_more_packets
+         * is set then that means there's no more pages after this one, so
+         * we set active to 0, break out of the loop, pack up our things and
+         * go home.
+         */
+        if (writer->no_more_packets) {
+          active = 0;
+          break;
+        } else if (!oggz_page_init (oggz)) {
 #ifdef DEBUG
-	  printf ("oggz_write: bytes_written == 0, DONE\n");
+          printf ("oggz_write: bytes_written == 0, DONE\n");
 #endif
-	  writer->state = OGGZ_MAKING_PACKETS;
-	}
+          writer->state = OGGZ_MAKING_PACKETS;
+        }
       }
 
       remaining -= bytes_written;



More information about the commits mailing list