[xiph-commits] r3618 - liboggz/trunk/src/tools/oggz-chop
conrad at svn.annodex.net
conrad at svn.annodex.net
Sun Jun 29 06:51:55 PDT 2008
Author: conrad
Date: 2008-06-29 06:51:55 -0700 (Sun, 29 Jun 2008)
New Revision: 3618
Modified:
liboggz/trunk/src/tools/oggz-chop/oggz-chop.c
Log:
oggz-chop: add writing of skeleton fisbones and eos, and enable skeleton generation.
Output files now contain a skeleton track, and if the input file contained a
skeleton track then its message headers are preserved.
Modified: liboggz/trunk/src/tools/oggz-chop/oggz-chop.c
===================================================================
--- liboggz/trunk/src/tools/oggz-chop/oggz-chop.c 2008-06-29 13:21:48 UTC (rev 3617)
+++ liboggz/trunk/src/tools/oggz-chop/oggz-chop.c 2008-06-29 13:51:55 UTC (rev 3618)
@@ -119,7 +119,7 @@
state_init (OCState * state)
{
/* Initialize fishead presentation time */
- state->fishead.ptime_n = state->start / (ogg_int64_t)1000;
+ state->fishead.ptime_n = state->start * (ogg_int64_t)1000;
state->fishead.ptime_d = 1000;
/* Initialize track table and page accumulator */
@@ -294,57 +294,133 @@
}
/************************************************************
- * chop
+ * Skeleton
*/
-/*
- * OggzReadPageCallback read_plain
- *
- * A page reading callback for tracks without granuleshift.
- */
+static long
+skeleton_write_packet (OCState * state, ogg_packet * op)
+{
+ int iret;
+ long ret;
+
+ op->packetno = -1;
+ iret = oggz_write_feed (state->skeleton_writer, op, state->skeleton_serialno,
+ OGGZ_FLUSH_BEFORE|OGGZ_FLUSH_AFTER, NULL);
+
+ ret = oggz_run (state->skeleton_writer);
+ fflush (state->outfile);
+
+ return ret;
+}
+
+const char * type_names[] = {
+ "video/theora",
+ "audio/vorbis",
+ "audio/speex",
+ "audio/x-oggpcm",
+ "text/cmml",
+ "application/x-annodex-2",
+ NULL, /* Skeleton */
+ "audio/flac",
+ "audio/flac",
+ NULL, /* AnxData */
+ "audio/celt",
+ "application/x-kate",
+ NULL /* UNKNOWN */
+};
+
static int
-read_plain (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+fisbone_init (OGGZ * oggz, OCState * state, OCTrackState * ts, long serialno)
{
- OCState * state = (OCState *)user_data;
+ OggzStreamContent content_type;
+ const char * name;
+ int len;
+
+ if (ts == NULL) return -1;
+
+ ts->fisbone.serial_no = serialno;
+ ts->fisbone.nr_header_packet = oggz_stream_get_numheaders (oggz, serialno);
+ oggz_get_granulerate (oggz, serialno, &ts->fisbone.granule_rate_n, &ts->fisbone.granule_rate_d);
+ ts->fisbone.start_granule = 0;
+ ts->fisbone.preroll = 0;
+ ts->fisbone.granule_shift = (unsigned char) oggz_get_granuleshift (oggz, serialno);
+ if (state->original_had_skeleton) {
+ /* Wait, and copy over message headers from original */
+ ts->fisbone.message_header_fields = NULL;
+ ts->fisbone.current_header_size = FISBONE_SIZE;
+ } else {
+ /* XXX: C99 */
+#define CONTENT_TYPE_FMT "Content-Type: %s\r\n"
+ content_type = oggz_stream_get_content (oggz, serialno);
+ name = type_names[content_type];
+ len = snprintf (NULL, 0, CONTENT_TYPE_FMT, name);
+ ts->fisbone.message_header_fields = malloc(len+1);
+ snprintf (ts->fisbone.message_header_fields, len+1, CONTENT_TYPE_FMT, name);
+ ts->fisbone.current_header_size = len+1;
+ }
+
+ return 0;
+}
+
+static long
+fisbones_write (OCState * state)
+{
OCTrackState * ts;
- double page_time;
- long gp;
+ long serialno;
+ ogg_packet op;
+ int i, ntracks, ret = -1001;
- ts = oggz_table_lookup (state->tracks, serialno);
+ if (!state->do_skeleton) return -1;
- page_time = oggz_tell_units (oggz) / 1000.0;
+ ntracks = oggz_table_size (state->tracks);
-#ifdef DEBUG
- printf ("page_time: %g\tspan (%g, %g)\n", page_time, state->start, state->end);
- printf ("\tpageno: %d, numheaders %d\n", ogg_page_pageno(og),
- oggz_stream_get_numheaders (oggz, serialno));
-#endif
+ /* Write fisbones */
+ for (i=0; i < ntracks; i++) {
+ ts = oggz_table_nth (state->tracks, i, &serialno);
+ ret = ogg_from_fisbone (&ts->fisbone, &op);
+ ret = skeleton_write_packet (state, &op);
+ _ogg_free (op.packet);
+ }
- if (page_time < state->start) {
- if ((gp = ogg_page_granulepos (og)) != -1)
- ts->fisbone.start_granule = ogg_page_granulepos (og);
- } else if (page_time >= state->start &&
- (state->end == -1 || page_time <= state->end)) {
- if (!ts->rec_skeleton) {
-#ifdef DEBUG
- printf ("read_plain: start granule for serialno %010ld: %ld\n",
- serialno, ts->fisbone.start_granule);
-#endif
- ts->rec_skeleton = 1;
- }
- fwrite_ogg_page (state->outfile, og);
- } else if (state->end != -1.0 && page_time > state->end) {
- /* This is the first page past the end time; set EOS */
- _ogg_page_set_eos (og);
- fwrite_ogg_page (state->outfile, og);
+ /* Write Skeleton EOS page */
+ memset (&op, 0, sizeof(op));
+ op.e_o_s = 1;
+ ret = skeleton_write_packet (state, &op);
- /* Stop handling this track */
- oggz_set_read_page (oggz, serialno, NULL, NULL);
+ return ret;
+}
+
+static int
+fishead_update (OCState * state, const ogg_page * og)
+{
+ fishead_packet fishead;
+
+ fishead_from_ogg_page (og, &fishead);
+ state->fishead.btime_n = fishead.btime_n;
+ state->fishead.btime_d = fishead.btime_d;
+
+ return 0;
+}
+
+static long
+fishead_write (OCState * state)
+{
+ ogg_packet op;
+ int ret = -1001;
+
+ if (state->do_skeleton) {
+ ogg_from_fishead (&state->fishead, &op);
+ ret = skeleton_write_packet (state, &op);
+ _ogg_free (op.packet);
}
- return OGGZ_CONTINUE;
+ return ret;
}
+/************************************************************
+ * chop
+ */
+
static int
write_accum (OCState * state)
{
@@ -430,7 +506,91 @@
return 0;
}
+/* Forward declaration */
+static int
+read_plain (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data);
+
+static int
+chop_glue (OCState * state, OGGZ * oggz)
+{
+ int i, ntracks;
+ long serialno;
+ OCTrackState * ts;
+
+ if (state->status < OC_WRITTEN_ACCUM) {
+ /* Write in fisbones */
+ fisbones_write (state);
+
+ /* Write out accumulated pages */
+ write_accum (state);
+
+ /* Switch all tracks to the plain page reader */
+ ntracks = oggz_table_size (state->tracks);
+ for (i=0; i < ntracks; i++) {
+ ts = oggz_table_nth (state->tracks, i, &serialno);
+ oggz_set_read_page (oggz, serialno, read_plain, state);
+ }
+ }
+
+ state->status = OC_WRITTEN_ACCUM;
+
+ return 0;
+}
+
/*
+ * OggzReadPageCallback read_plain
+ *
+ * A page reading callback for tracks without granuleshift.
+ */
+static int
+read_plain (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ OCState * state = (OCState *)user_data;
+ OCTrackState * ts;
+ double page_time;
+ long gp;
+
+ ts = oggz_table_lookup (state->tracks, serialno);
+
+ page_time = oggz_tell_units (oggz) / 1000.0;
+
+#ifdef DEBUG
+ printf ("page_time: %g\tspan (%g, %g)\n", page_time, state->start, state->end);
+ printf ("\tpageno: %d, numheaders %d\n", ogg_page_pageno(og),
+ oggz_stream_get_numheaders (oggz, serialno));
+#endif
+
+ if (page_time < state->start) {
+ if ((gp = ogg_page_granulepos (og)) != -1)
+ ts->fisbone.start_granule = ogg_page_granulepos (og);
+ } else if (page_time >= state->start &&
+ (state->end == -1 || page_time <= state->end)) {
+
+ if (state->status < OC_WRITTEN_ACCUM) {
+ chop_glue (state, oggz);
+ }
+
+ if (!ts->rec_skeleton) {
+#ifdef DEBUG
+ printf ("read_plain: start granule for serialno %010ld: %ld\n",
+ serialno, ts->fisbone.start_granule);
+#endif
+ ts->rec_skeleton = 1;
+ }
+ fwrite_ogg_page (state->outfile, og);
+ } else if (state->end != -1.0 && page_time > state->end) {
+ /* This is the first page past the end time; set EOS */
+ _ogg_page_set_eos (og);
+ fwrite_ogg_page (state->outfile, og);
+
+ /* Stop handling this track */
+ oggz_set_read_page (oggz, serialno, NULL, NULL);
+ }
+
+ return OGGZ_CONTINUE;
+}
+
+/*
* OggzReadPageCallback read_gs
*
* A page reading callback for tracks with granuleshift.
@@ -452,8 +612,8 @@
accum_size = oggz_table_size (ts->page_accum);
if (page_time >= state->start) {
- /* Write out accumulated pages */
- write_accum (state);
+ /* Glue in fisbones, write out accumulated pages */
+ chop_glue (state, oggz);
if (!ts->rec_skeleton) {
#ifdef DEBUG
@@ -506,7 +666,7 @@
{
OCState * state = (OCState *)user_data;
OCTrackState * ts;
- int content_type;
+ OggzStreamContent content_type;
fisbone_packet fisbone;
content_type = oggz_stream_get_content(oggz, serialno);
@@ -537,79 +697,12 @@
}
static int
-fisbone_init (OGGZ * oggz, OCState * state, OCTrackState * ts, long serialno)
-{
- const char * content_type;
- int len;
-
- if (ts == NULL) return -1;
-
- ts->fisbone.serial_no = serialno;
- ts->fisbone.nr_header_packet = oggz_stream_get_numheaders (oggz, serialno);
- oggz_get_granulerate (oggz, serialno, &ts->fisbone.granule_rate_n, &ts->fisbone.granule_rate_d);
- ts->fisbone.start_granule = 0;
- ts->fisbone.preroll = 0;
- ts->fisbone.granule_shift = (unsigned char) oggz_get_granuleshift (oggz, serialno);
- if (state->original_had_skeleton) {
- /* Wait, and copy over message headers from original */
- ts->fisbone.message_header_fields = NULL;
- ts->fisbone.current_header_size = FISBONE_SIZE;
- } else {
- /* XXX: C99 */
-#define CONTENT_TYPE_FMT "Content-Type: %s\r\n"
- content_type = oggz_stream_get_content_type (oggz, serialno);
- len = snprintf (NULL, 0, CONTENT_TYPE_FMT, content_type);
- ts->fisbone.message_header_fields = malloc(len+1);
- snprintf (ts->fisbone.message_header_fields, len+1, CONTENT_TYPE_FMT, content_type);
- ts->fisbone.current_header_size = len+1;
- }
-
- return 0;
-}
-
-static int
-fishead_update (OCState * state, const ogg_page * og)
-{
- fishead_packet fishead;
-
- fishead_from_ogg_page (og, &fishead);
- state->fishead.btime_n = fishead.btime_n;
- state->fishead.btime_d = fishead.btime_d;
-
- return 0;
-}
-
-static long
-skeleton_write_packet (OCState * state, ogg_packet * op)
-{
- oggz_write_feed (state->skeleton_writer, op, state->skeleton_serialno,
- OGGZ_FLUSH_BEFORE|OGGZ_FLUSH_AFTER, NULL);
- return oggz_run (state->skeleton_writer);
-}
-
-static long
-fishead_write (OCState * state)
-{
- ogg_packet op;
- int ret = -1001;
-
- if (state->do_skeleton) {
- ogg_from_fishead (&state->fishead, &op);
- ret = skeleton_write_packet (state, &op);
- _ogg_free (op.packet);
- }
-
- return ret;
-}
-
-
-static int
read_bos (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
{
OCState * state = (OCState *)user_data;
OCTrackState * ts;
double page_time;
- int content_type;
+ OggzStreamContent content_type;
if (ogg_page_bos (OGG_PAGE_CONST(og))) {
content_type = oggz_stream_get_content(oggz, serialno);
@@ -646,6 +739,7 @@
{
OGGZ * oggz;
+ state->do_skeleton = 1;
state_init (state);
if (strcmp (state->infilename, "-") == 0) {
@@ -680,6 +774,11 @@
oggz_close (oggz);
+#if 0
+ if (state->do_skeleton)
+ oggz_close (state->skeleton_writer);
+#endif
+
if (state->outfilename != NULL) {
fclose (state->outfile);
}
More information about the commits
mailing list