[xiph-commits] r3880 - liboggz/trunk/src/tools/oggz-chop
conrad at svn.annodex.net
conrad at svn.annodex.net
Mon Mar 16 21:19:03 PDT 2009
Author: conrad
Date: 2009-03-16 21:19:03 -0700 (Mon, 16 Mar 2009)
New Revision: 3880
Modified:
liboggz/trunk/src/tools/oggz-chop/oggz-chop.c
Log:
oggz-chop: verify that the earliest_new page written from a
page accumulator actually contains packets from the new GOP.
Previously we always included the last page with granulepos
from the previous GOP, in case it also contained the start of a
new packet. We now explicitly check if we can rule out this
possibility by remembering whether the successive page was
continued: we only include the earlier page if so.
This avoids adding preceding garbage where possible, ie. if
the keyframe starts a new page. This is uncommon with current
Theora encoders, but it is the normal (advised) case for Dirac.
Modified: liboggz/trunk/src/tools/oggz-chop/oggz-chop.c
===================================================================
--- liboggz/trunk/src/tools/oggz-chop/oggz-chop.c 2009-03-17 04:18:55 UTC (rev 3879)
+++ liboggz/trunk/src/tools/oggz-chop/oggz-chop.c 2009-03-17 04:19:03 UTC (rev 3880)
@@ -262,10 +262,17 @@
int i, accum_size;
int e, earliest_new; /* Index into page accumulator of the earliest page that
* contains a packet from the new GOP */
+ int succ_continued; /* Successor page is continued */
OCPageAccum * pa;
if (ts == NULL || ts->page_accum == NULL) return 0;
+ /* Upon entry, the next page is the one most recently read; we only get here
+ * if that page is continued, otherwise the accumulator is simply cleared,
+ * in read_gs() and read_dirac() below.
+ */
+ succ_continued = 1;
+
earliest_new = accum_size = oggz_table_size (ts->page_accum);
/* Working backwards through the page accumulator ... */
@@ -273,15 +280,30 @@
pa = (OCPageAccum *) oggz_table_lookup (ts->page_accum, i);
/* If we have a page with granulepos, it necessarily contains the end
- * of a packet from an earlier GOP, and may contain the start of
- * a packet from the new GOP. Thus it is the earliest page that we need
- * to recover.
- * We are working backwards, so we can break out when we have found it.
+ * of a packet from an earlier GOP, and may contain the start of a packet
+ * from the new GOP. If so, it is the earliest page to recover.
*/
if (ogg_page_granulepos (pa->og) != -1) {
earliest_new = i;
+
+ /* If the successor page was not continued, ie. it began a packet,
+ * then this page only contains packets from the previous GOP or earlier.
+ * In this case, we can be sure that the successor is the earliest_new
+ * page to use.
+ */
+ if (!succ_continued)
+ earliest_new++;
+
+ /* We are working backwards, so we can break out when we have found
+ * the earliest page to recover.
+ */
break;
}
+
+ /* Update succ_continued flag; we are working backwards, so this page
+ * is the successor to the one we will consider on the next iteration.
+ */
+ succ_continued = ogg_page_continued(OGG_PAGE_CONST(pa->og));
}
/* If all accumulated pages have no granulepos, keep them,
More information about the commits
mailing list