[xiph-commits] r3498 - in liboggz/trunk: . src/tools
src/tools/oggz-chop
conrad at svn.annodex.net
conrad at svn.annodex.net
Wed Feb 27 01:15:56 PST 2008
Author: conrad
Date: 2008-02-27 01:15:55 -0800 (Wed, 27 Feb 2008)
New Revision: 3498
Added:
liboggz/trunk/src/tools/oggz-chop/
liboggz/trunk/src/tools/oggz-chop/oggz-chop.c
Removed:
liboggz/trunk/src/tools/oggz-chop.c
Modified:
liboggz/trunk/configure.ac
liboggz/trunk/src/tools/Makefile.am
Log:
move oggz-chop into its own source dir
Modified: liboggz/trunk/configure.ac
===================================================================
--- liboggz/trunk/configure.ac 2008-02-26 08:29:10 UTC (rev 3497)
+++ liboggz/trunk/configure.ac 2008-02-27 09:15:55 UTC (rev 3498)
@@ -145,7 +145,7 @@
if test "x${ac_enable_write}" = xyes ; then
AC_DEFINE(OGGZ_CONFIG_WRITE, [1], [Build writing support])
if test "x${ac_enable_read}" = xyes ; then
- oggz_rw_programs="oggzrip oggzmerge oggz-comment oggz-validate"
+ oggz_rw_programs="oggzrip oggzmerge oggz-chop oggz-comment oggz-validate"
fi
else
AC_DEFINE(OGGZ_CONFIG_WRITE, [0], [Do not build writing support])
@@ -413,6 +413,7 @@
src/liboggz/Makefile
src/tools/Makefile
src/tools/oggzdiff
+src/tools/oggz-chop/Makefile
src/tests/Makefile
src/examples/Makefile
oggz.pc
@@ -436,7 +437,8 @@
Tools:
- ${oggz_read_programs} ${oggz_rw_programs}
+ ${oggz_read_programs}
+ ${oggz_rw_programs}
Installation paths:
Modified: liboggz/trunk/src/tools/Makefile.am
===================================================================
--- liboggz/trunk/src/tools/Makefile.am 2008-02-26 08:29:10 UTC (rev 3497)
+++ liboggz/trunk/src/tools/Makefile.am 2008-02-27 09:15:55 UTC (rev 3498)
@@ -1,5 +1,7 @@
## Process this file with automake to produce Makefile.in
+SUBDIRS = oggz-chop
+
EXTRA_DIST = oggzdiff
bin_SCRIPTS = oggzdiff
@@ -14,7 +16,7 @@
oggz_read_noinst_programs =
if OGGZ_CONFIG_WRITE
-oggz_rw_programs = oggzmerge oggzrip oggz-chop oggz-validate oggz-comment oggz-sort
+oggz_rw_programs = oggzmerge oggzrip oggz-validate oggz-comment oggz-sort
oggz_rw_noinst_programs = oggz-basetime
endif
@@ -29,9 +31,6 @@
oggzinfo_SOURCES = oggzinfo.c oggz_tools.c skeleton.c
oggzinfo_LDADD = $(OGGZ_LIBS) -lm
-oggz_chop_SOURCES = oggz-chop.c oggz_tools.c
-oggz_chop_LDADD = $(OGGZ_LIBS)
-
oggz_comment_SOURCES = oggz-comment.c oggz_tools.c
oggz_comment_LDADD = $(OGGZ_LIBS)
Copied: liboggz/trunk/src/tools/oggz-chop/oggz-chop.c (from rev 3497, liboggz/trunk/src/tools/oggz-chop.c)
===================================================================
--- liboggz/trunk/src/tools/oggz-chop/oggz-chop.c (rev 0)
+++ liboggz/trunk/src/tools/oggz-chop/oggz-chop.c 2008-02-27 09:15:55 UTC (rev 3498)
@@ -0,0 +1,453 @@
+
+/*
+ Copyright (C) 2008 Annodex Association
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Annodex Association nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ASSOCIATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+
+
+#include <oggz/oggz.h>
+
+static char * progname;
+
+static void
+usage (char * progname)
+{
+ printf ("Usage: %s [options] filename\n", progname);
+ printf ("Chop an Ogg file.\n");
+ printf ("\nOutput options\n");
+ printf (" -o filename, --output filename\n");
+ printf (" Specify output filename\n");
+ printf (" -s start_time, --start start_time\n");
+ printf (" Specify start time\n");
+ printf (" -e end_time, --end end_time\n");
+ printf (" Specify end time\n");
+ printf ("\nMiscellaneous options\n");
+ printf (" -h, --help Display this help and exit\n");
+ printf (" -v, --version Output version information and exit\n");
+ printf ("\n");
+ printf ("Please report bugs to <ogg-dev at xiph.org>\n");
+}
+
+/************************************************************
+ * OCState
+ */
+
+typedef struct _OCState {
+ OggzTable * tracks;
+ FILE * outfile;
+ double start;
+ double end;
+} OCState;
+
+/************************************************************
+ * OCTrackState
+ */
+
+typedef struct _OCTrackState {
+ OggzTable * page_accum;
+
+ int headers_remaining;
+
+ long start_granule;
+
+ /* Greatest previously inferred keyframe value */
+ ogg_int64_t prev_keyframe;
+
+} OCTrackState;
+
+static OCTrackState *
+track_state_new (void)
+{
+ OCTrackState * ts;
+
+ ts = (OCTrackState *) malloc (sizeof(*ts));
+
+ memset (ts, 0, sizeof(*ts));
+ ts->page_accum = oggz_table_new();
+
+ return ts;
+}
+
+static void
+track_state_delete (OCTrackState * ts)
+{
+ if (ts == NULL) return;
+
+ /* XXX: delete accumulated pages */
+ oggz_table_delete (ts->page_accum);
+
+ free (ts);
+
+ return;
+}
+
+/* Add a track to the overall state */
+static OCTrackState *
+track_state_add (OggzTable * state, long serialno)
+{
+ OCTrackState * ts;
+
+ ts = track_state_new ();
+ if (oggz_table_insert (state, serialno, ts) == ts) {
+ return ts;
+ } else {
+ track_state_delete (ts);
+ return NULL;
+ }
+}
+
+/************************************************************
+ * ogg_page helpers
+ */
+
+static ogg_page *
+_ogg_page_copy (const ogg_page * og)
+{
+ ogg_page * new_og;
+
+ new_og = malloc (sizeof (*og));
+ new_og->header = malloc (og->header_len);
+ new_og->header_len = og->header_len;
+ memcpy (new_og->header, og->header, og->header_len);
+ new_og->body = malloc (og->body_len);
+ new_og->body_len = og->body_len;
+ memcpy (new_og->body, og->body, og->body_len);
+
+ return new_og;
+}
+
+static void
+_ogg_page_free (const ogg_page * og)
+{
+ if (og == NULL) return;
+
+ free (og->header);
+ free (og->body);
+ free ((ogg_page *)og);
+}
+
+static void
+_ogg_page_set_eos (const ogg_page * og)
+{
+ if (og == NULL) return;
+
+ og->header[5] |= 0x04;
+ ogg_page_checksum_set (og);
+}
+
+static void
+fwrite_ogg_page (FILE * outfile, ogg_page * og)
+{
+ if (og == NULL) return;
+
+ fwrite (og->header, 1, og->header_len, outfile);
+ fwrite (og->body, 1, og->body_len, outfile);
+}
+
+/************************************************************
+ * chop
+ */
+
+/*
+ * 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;
+
+ ts = oggz_table_lookup (state->tracks, serialno);
+
+ page_time = oggz_tell_units (oggz) / 1000.0;
+
+#if 0
+ 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 &&
+ (state->end == -1 || page_time <= state->end)) {
+ 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.
+ */
+static int
+read_gs (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ OCState * state = (OCState *)user_data;
+ OCTrackState * ts;
+ double page_time;
+ ogg_int64_t granulepos, keyframe;
+ int granuleshift, i, accum_size;
+ ogg_page * accum_og;
+
+ page_time = oggz_tell_units (oggz) / 1000.0;
+
+ ts = oggz_table_lookup (state->tracks, serialno);
+ accum_size = oggz_table_size (ts->page_accum);
+
+ if (page_time >= state->start) {
+ /* Write out accumulated pages */
+ for (i = 0; i < accum_size; i++) {
+ accum_og = (ogg_page *)oggz_table_lookup (ts->page_accum, i);
+ fwrite_ogg_page (state->outfile, accum_og);
+ _ogg_page_free (accum_og);
+ }
+ oggz_table_delete (ts->page_accum);
+ ts->page_accum = NULL;
+
+ /* Switch to the plain page reader */
+ oggz_set_read_page (oggz, serialno, read_plain, state);
+ return read_plain (oggz, og, serialno, user_data);
+ } /* else { ... */
+
+ granulepos = ogg_page_granulepos (og);
+ if (granulepos != -1) {
+ granuleshift = oggz_get_granuleshift (oggz, serialno);
+ keyframe = granulepos >> granuleshift;
+
+ if (keyframe != ts->prev_keyframe) {
+ /* Clear the page accumulator */
+ for (i = accum_size; i >= 0; i--) {
+ _ogg_page_free ((ogg_page *)oggz_table_lookup (ts->page_accum, i));
+ oggz_table_remove (ts->page_accum, (long)i);
+ }
+ accum_size = 0;
+
+ /* Record this as prev_keyframe */
+ ts->prev_keyframe = keyframe;
+ }
+ }
+
+ /* Add a copy of this to the page accumulator */
+ oggz_table_insert (ts->page_accum, accum_size, _ogg_page_copy (og));
+
+ return OGGZ_CONTINUE;
+}
+
+/*
+ * OggzReadPageCallback read_headers
+ *
+ * A page reading callback for header pages
+ */
+static int
+read_headers (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ OCState * state = (OCState *)user_data;
+ OCTrackState * ts;
+
+ fwrite_ogg_page (state->outfile, og);
+
+ ts = oggz_table_lookup (state->tracks, serialno);
+ ts->headers_remaining -= ogg_page_packets (og);
+
+ if (ts->headers_remaining <= 0) {
+ if (state->start == 0.0 || oggz_get_granuleshift (oggz, serialno) == 0) {
+ oggz_set_read_page (oggz, serialno, read_plain, state);
+ } else {
+ oggz_set_read_page (oggz, serialno, read_gs, state);
+ }
+ }
+
+ return OGGZ_CONTINUE;
+}
+
+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;
+
+ if (ogg_page_bos (og)) {
+ ts = track_state_add (state->tracks, serialno);
+ ts->headers_remaining = oggz_stream_get_numheaders (oggz, serialno);
+
+ oggz_set_read_page (oggz, serialno, read_headers, state);
+ read_headers (oggz, og, serialno, user_data);
+ } else {
+ /* Deregister the catch-all page reading callback */
+ oggz_set_read_page (oggz, -1, NULL, NULL);
+ }
+
+ return OGGZ_CONTINUE;
+}
+
+static int
+chop (char * infilename, char * outfilename, double start, double end)
+{
+ OCState state;
+ OGGZ * oggz;
+
+ state.tracks = oggz_table_new ();
+
+ if (strcmp (infilename, "-") == 0) {
+ oggz = oggz_open_stdio (stdin, OGGZ_READ|OGGZ_AUTO);
+ } else {
+ oggz = oggz_open (infilename, OGGZ_READ|OGGZ_AUTO);
+ }
+
+ if (outfilename == NULL) {
+ state.outfile = stdout;
+ } else {
+ state.outfile = fopen (outfilename, "wb");
+ if (state.outfile == NULL) {
+ fprintf (stderr, "%s: unable to open output file %s\n",
+ progname, outfilename);
+ return -1;
+ }
+ }
+
+ state.start = start;
+ state.end = end;
+
+ /* set up a demux filter */
+ oggz_set_read_page (oggz, -1, read_bos, &state);
+
+ oggz_run_set_blocksize (oggz, 1024*1024);
+ oggz_run (oggz);
+
+ oggz_close (oggz);
+
+ return 0;
+}
+
+int
+main (int argc, char * argv[])
+{
+ int show_version = 0;
+ int show_help = 0;
+ double start = 0.0, end = -1.0;
+ char * infilename = NULL, * outfilename = NULL;
+ int i;
+
+ progname = argv[0];
+
+ if (argc < 2) {
+ usage (progname);
+ return (1);
+ }
+
+ while (1) {
+ char * optstring = "s:e:o:hv";
+
+#ifdef HAVE_GETOPT_LONG
+ static struct option long_options[] = {
+ {"output", required_argument, 0, 'o'},
+ {"format", required_argument, 0, 'f'},
+ {"keyframe", no_argument, 0, 'k'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'v'},
+ {0,0,0,0}
+ };
+
+ i = getopt_long(argc, argv, optstring, long_options, NULL);
+#else
+ i = getopt (argc, argv, optstring);
+#endif
+ if (i == -1) break;
+ if (i == ':') {
+ usage (progname);
+ goto exit_err;
+ }
+
+ switch (i) {
+ case 's': /* start */
+ start = atof (optarg);
+ break;
+ case 'e': /* end */
+ end = atof (optarg);
+ break;
+ case 'h': /* help */
+ show_help = 1;
+ break;
+ case 'v': /* version */
+ show_version = 1;
+ break;
+ case 'o': /* output */
+ outfilename = optarg;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (show_version) {
+ printf ("%s version " VERSION "\n", progname);
+ }
+
+ if (show_help) {
+ usage (progname);
+ }
+
+ if (show_version || show_help) {
+ goto exit_ok;
+ }
+
+ if (optind >= argc) {
+ usage (progname);
+ goto exit_err;
+ }
+
+ infilename = argv[optind++];
+
+ return chop (infilename, outfilename, start, end);
+
+exit_ok:
+ return 0;
+
+exit_err:
+ return 1;
+}
Deleted: liboggz/trunk/src/tools/oggz-chop.c
===================================================================
--- liboggz/trunk/src/tools/oggz-chop.c 2008-02-26 08:29:10 UTC (rev 3497)
+++ liboggz/trunk/src/tools/oggz-chop.c 2008-02-27 09:15:55 UTC (rev 3498)
@@ -1,453 +0,0 @@
-
-/*
- Copyright (C) 2008 Annodex Association
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Annodex Association nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ASSOCIATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-
-
-#include <oggz/oggz.h>
-
-static char * progname;
-
-static void
-usage (char * progname)
-{
- printf ("Usage: %s [options] filename\n", progname);
- printf ("Chop an Ogg file.\n");
- printf ("\nOutput options\n");
- printf (" -o filename, --output filename\n");
- printf (" Specify output filename\n");
- printf (" -s start_time, --start start_time\n");
- printf (" Specify start time\n");
- printf (" -e end_time, --end end_time\n");
- printf (" Specify end time\n");
- printf ("\nMiscellaneous options\n");
- printf (" -h, --help Display this help and exit\n");
- printf (" -v, --version Output version information and exit\n");
- printf ("\n");
- printf ("Please report bugs to <ogg-dev at xiph.org>\n");
-}
-
-/************************************************************
- * OCState
- */
-
-typedef struct _OCState {
- OggzTable * tracks;
- FILE * outfile;
- double start;
- double end;
-} OCState;
-
-/************************************************************
- * OCTrackState
- */
-
-typedef struct _OCTrackState {
- OggzTable * page_accum;
-
- int headers_remaining;
-
- long start_granule;
-
- /* Greatest previously inferred keyframe value */
- ogg_int64_t prev_keyframe;
-
-} OCTrackState;
-
-static OCTrackState *
-track_state_new (void)
-{
- OCTrackState * ts;
-
- ts = (OCTrackState *) malloc (sizeof(*ts));
-
- memset (ts, 0, sizeof(*ts));
- ts->page_accum = oggz_table_new();
-
- return ts;
-}
-
-static void
-track_state_delete (OCTrackState * ts)
-{
- if (ts == NULL) return;
-
- /* XXX: delete accumulated pages */
- oggz_table_delete (ts->page_accum);
-
- free (ts);
-
- return;
-}
-
-/* Add a track to the overall state */
-static OCTrackState *
-track_state_add (OggzTable * state, long serialno)
-{
- OCTrackState * ts;
-
- ts = track_state_new ();
- if (oggz_table_insert (state, serialno, ts) == ts) {
- return ts;
- } else {
- track_state_delete (ts);
- return NULL;
- }
-}
-
-/************************************************************
- * ogg_page helpers
- */
-
-static ogg_page *
-_ogg_page_copy (const ogg_page * og)
-{
- ogg_page * new_og;
-
- new_og = malloc (sizeof (*og));
- new_og->header = malloc (og->header_len);
- new_og->header_len = og->header_len;
- memcpy (new_og->header, og->header, og->header_len);
- new_og->body = malloc (og->body_len);
- new_og->body_len = og->body_len;
- memcpy (new_og->body, og->body, og->body_len);
-
- return new_og;
-}
-
-static void
-_ogg_page_free (const ogg_page * og)
-{
- if (og == NULL) return;
-
- free (og->header);
- free (og->body);
- free ((ogg_page *)og);
-}
-
-static void
-_ogg_page_set_eos (const ogg_page * og)
-{
- if (og == NULL) return;
-
- og->header[5] |= 0x04;
- ogg_page_checksum_set (og);
-}
-
-static void
-fwrite_ogg_page (FILE * outfile, ogg_page * og)
-{
- if (og == NULL) return;
-
- fwrite (og->header, 1, og->header_len, outfile);
- fwrite (og->body, 1, og->body_len, outfile);
-}
-
-/************************************************************
- * chop
- */
-
-/*
- * 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;
-
- ts = oggz_table_lookup (state->tracks, serialno);
-
- page_time = oggz_tell_units (oggz) / 1000.0;
-
-#if 0
- 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 &&
- (state->end == -1 || page_time <= state->end)) {
- 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.
- */
-static int
-read_gs (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
-{
- OCState * state = (OCState *)user_data;
- OCTrackState * ts;
- double page_time;
- ogg_int64_t granulepos, keyframe;
- int granuleshift, i, accum_size;
- ogg_page * accum_og;
-
- page_time = oggz_tell_units (oggz) / 1000.0;
-
- ts = oggz_table_lookup (state->tracks, serialno);
- accum_size = oggz_table_size (ts->page_accum);
-
- if (page_time >= state->start) {
- /* Write out accumulated pages */
- for (i = 0; i < accum_size; i++) {
- accum_og = (ogg_page *)oggz_table_lookup (ts->page_accum, i);
- fwrite_ogg_page (state->outfile, accum_og);
- _ogg_page_free (accum_og);
- }
- oggz_table_delete (ts->page_accum);
- ts->page_accum = NULL;
-
- /* Switch to the plain page reader */
- oggz_set_read_page (oggz, serialno, read_plain, state);
- return read_plain (oggz, og, serialno, user_data);
- } /* else { ... */
-
- granulepos = ogg_page_granulepos (og);
- if (granulepos != -1) {
- granuleshift = oggz_get_granuleshift (oggz, serialno);
- keyframe = granulepos >> granuleshift;
-
- if (keyframe != ts->prev_keyframe) {
- /* Clear the page accumulator */
- for (i = accum_size; i >= 0; i--) {
- _ogg_page_free ((ogg_page *)oggz_table_lookup (ts->page_accum, i));
- oggz_table_remove (ts->page_accum, (long)i);
- }
- accum_size = 0;
-
- /* Record this as prev_keyframe */
- ts->prev_keyframe = keyframe;
- }
- }
-
- /* Add a copy of this to the page accumulator */
- oggz_table_insert (ts->page_accum, accum_size, _ogg_page_copy (og));
-
- return OGGZ_CONTINUE;
-}
-
-/*
- * OggzReadPageCallback read_headers
- *
- * A page reading callback for header pages
- */
-static int
-read_headers (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
-{
- OCState * state = (OCState *)user_data;
- OCTrackState * ts;
-
- fwrite_ogg_page (state->outfile, og);
-
- ts = oggz_table_lookup (state->tracks, serialno);
- ts->headers_remaining -= ogg_page_packets (og);
-
- if (ts->headers_remaining <= 0) {
- if (state->start == 0.0 || oggz_get_granuleshift (oggz, serialno) == 0) {
- oggz_set_read_page (oggz, serialno, read_plain, state);
- } else {
- oggz_set_read_page (oggz, serialno, read_gs, state);
- }
- }
-
- return OGGZ_CONTINUE;
-}
-
-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;
-
- if (ogg_page_bos (og)) {
- ts = track_state_add (state->tracks, serialno);
- ts->headers_remaining = oggz_stream_get_numheaders (oggz, serialno);
-
- oggz_set_read_page (oggz, serialno, read_headers, state);
- read_headers (oggz, og, serialno, user_data);
- } else {
- /* Deregister the catch-all page reading callback */
- oggz_set_read_page (oggz, -1, NULL, NULL);
- }
-
- return OGGZ_CONTINUE;
-}
-
-static int
-chop (char * infilename, char * outfilename, double start, double end)
-{
- OCState state;
- OGGZ * oggz;
-
- state.tracks = oggz_table_new ();
-
- if (strcmp (infilename, "-") == 0) {
- oggz = oggz_open_stdio (stdin, OGGZ_READ|OGGZ_AUTO);
- } else {
- oggz = oggz_open (infilename, OGGZ_READ|OGGZ_AUTO);
- }
-
- if (outfilename == NULL) {
- state.outfile = stdout;
- } else {
- state.outfile = fopen (outfilename, "wb");
- if (state.outfile == NULL) {
- fprintf (stderr, "%s: unable to open output file %s\n",
- progname, outfilename);
- return -1;
- }
- }
-
- state.start = start;
- state.end = end;
-
- /* set up a demux filter */
- oggz_set_read_page (oggz, -1, read_bos, &state);
-
- oggz_run_set_blocksize (oggz, 1024*1024);
- oggz_run (oggz);
-
- oggz_close (oggz);
-
- return 0;
-}
-
-int
-main (int argc, char * argv[])
-{
- int show_version = 0;
- int show_help = 0;
- double start = 0.0, end = -1.0;
- char * infilename = NULL, * outfilename = NULL;
- int i;
-
- progname = argv[0];
-
- if (argc < 2) {
- usage (progname);
- return (1);
- }
-
- while (1) {
- char * optstring = "s:e:o:hv";
-
-#ifdef HAVE_GETOPT_LONG
- static struct option long_options[] = {
- {"output", required_argument, 0, 'o'},
- {"format", required_argument, 0, 'f'},
- {"keyframe", no_argument, 0, 'k'},
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'v'},
- {0,0,0,0}
- };
-
- i = getopt_long(argc, argv, optstring, long_options, NULL);
-#else
- i = getopt (argc, argv, optstring);
-#endif
- if (i == -1) break;
- if (i == ':') {
- usage (progname);
- goto exit_err;
- }
-
- switch (i) {
- case 's': /* start */
- start = atof (optarg);
- break;
- case 'e': /* end */
- end = atof (optarg);
- break;
- case 'h': /* help */
- show_help = 1;
- break;
- case 'v': /* version */
- show_version = 1;
- break;
- case 'o': /* output */
- outfilename = optarg;
- break;
- default:
- break;
- }
- }
-
- if (show_version) {
- printf ("%s version " VERSION "\n", progname);
- }
-
- if (show_help) {
- usage (progname);
- }
-
- if (show_version || show_help) {
- goto exit_ok;
- }
-
- if (optind >= argc) {
- usage (progname);
- goto exit_err;
- }
-
- infilename = argv[optind++];
-
- return chop (infilename, outfilename, start, end);
-
-exit_ok:
- return 0;
-
-exit_err:
- return 1;
-}
More information about the commits
mailing list