Commit 7e8bc47d authored by conrad's avatar conrad

updated to 0.8.0


git-svn-id: http://svn.annodex.net/liboggz/trunk@346 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 8bb668dc
......@@ -3,24 +3,39 @@ AC_INIT
AC_CONFIG_SRCDIR([src/liboggz/oggz.c])
AC_PREREQ(2.53)
AC_CONFIG_AUX_DIR(autotools)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(liboggz, 0.5.43)
AM_INIT_AUTOMAKE(liboggz, 0.8.0)
AM_CONFIG_HEADER(config.h)
SHARED_VERSION_INFO="0:5:0"
SHARED_VERSION_INFO="1:0:0"
SHLIB_VERSION_ARG=""
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
AC_PROG_RANLIB
AC_C_CONST
AC_C_BIGENDIAN
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h inttypes.h stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memmove])
# Check for doxygen
AC_CHECK_PROG(HAVE_DOXYGEN, doxygen, true, false)
......@@ -30,15 +45,15 @@ if test $HAVE_DOXYGEN = "false"; then
fi
# Check for docbook
AC_CHECK_PROG(HAVE_DOCBOOK, docbook2man, true, false)
AM_CONDITIONAL(HAVE_DOCBOOK,$HAVE_DOCBOOK)
dnl Check for types
AC_CHECK_PROG(HAVE_DOCBOOKTOMAN, docbook-to-man, true, false)
AM_CONDITIONAL(HAVE_DOCBOOKTOMAN,$HAVE_DOCBOOKTOMAN)
AC_CHECK_PROG(HAVE_DOCBOOK2HTML, docbook2html, true, false)
AM_CONDITIONAL(HAVE_DOCBOOK2HTML,$HAVE_DOCBOOK2HTML)
dnl Checks for libraries.
LIBS=""
# check for getopt in standard library
# check for getopt in a separate library
HAVE_GETOPT=no
AC_CHECK_LIB(getopt, getopt, HAVE_GETOPT="yes")
if test "x$HAVE_GETOPT" = xyes ; then
......@@ -46,6 +61,13 @@ if test "x$HAVE_GETOPT" = xyes ; then
AC_SUBST(GETOPT_LIBS)
fi
# check for getopt_long in standard library
HAVE_GETOPT_LONG=no
AC_CHECK_FUNC(getopt_long, HAVE_GETOPT_LONG="yes")
if test "x$HAVE_GETOPT_LONG" = xyes ; then
AC_DEFINE(HAVE_GETOPT_LONG, [], [Define to 1 if you have the 'getopt_long' function])
fi
dnl Overall configuration success flag
oggz_config_ok=yes
......@@ -211,6 +233,7 @@ src/Makefile
src/liboggz/Version_script
src/liboggz/Makefile
src/tools/Makefile
src/tools/oggzdiff
src/tests/Makefile
src/examples/Makefile
oggz.pc
......
......@@ -419,7 +419,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
IMAGE_PATH = .
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
......
docdir=$(prefix)/share/doc/@PACKAGE@
EXTRA_DIST = Doxyfile.in liboggz
EXTRA_DIST = Doxyfile.in \
forcefeed.fig forcefeed.eps forcefeed.png \
hungry.fig hungry.eps hungry.png \
oggzdump.1.sgml oggzdiff.1.sgml \
oggzdump.1 oggzdiff.1
all: doxygen-build.stamp
man_MANS = oggzdump.1 oggzdiff.1
doc_DATA = doxygen-build.stamp
html: oggzdump.1.html
if HAVE_DOCBOOKTOMAN
%.1: %.1.sgml
docbook-to-man $< > $@
else
%.1: %.1.sgml
endif
if HAVE_DOCBOOK2HTML
%.1.html: %.1.sgml
-docbook2html $<
mv index.html $@
endif
if HAVE_DOXYGEN
doxygen-build.stamp: Doxyfile $(top_srcdir)/include/oggz/*.h
doxygen-build.stamp: Doxyfile $(top_srcdir)/include/oggz/*.h $(top_srcdir)/src/examples/*.c
doxygen
touch doxygen-build.stamp
else
......@@ -14,6 +35,23 @@ doxygen-build.stamp:
touch doxygen-build.stamp
endif
dist_docdir = $(distdir)/liboggz
dist-hook:
if test -d liboggz; then \
mkdir $(dist_docdir); \
for dir in liboggz/*; do \
if test -d $$dir; then \
b=`basename $$dir`; \
mkdir $(dist_docdir)/$$b; \
for f in $$dir/*; do \
cp -p $$f $(dist_docdir)/$$b; \
done \
fi \
done \
fi
install-data-local: doxygen-build.stamp
$(mkinstalldirs) $(docdir)
if test -d liboggz; then \
......@@ -21,7 +59,9 @@ install-data-local: doxygen-build.stamp
if test -d $$dir; then \
b=`basename $$dir`; \
$(mkinstalldirs) $(docdir)/$$b; \
(cd $$dir && $(INSTALL_DATA) * $(docdir)/$$b) \
for f in $$dir/*; do \
$(INSTALL_DATA) $$f $(docdir)/$$b; \
done \
fi \
done \
fi
......
......@@ -2,5 +2,5 @@
# Include files to install
includedir = $(prefix)/include/oggz
include_HEADERS = oggz.h oggz_constants.h
include_HEADERS = oggz.h oggz_constants.h oggz_table.h
This diff is collapsed.
......@@ -39,6 +39,9 @@
/**
* Flags to oggz_new(), oggz_open(), and oggz_openfd().
* Can be or'ed together in the following combinations:
* - OGGZ_READ | OGGZ_AUTO
* - OGGZ_WRITE | OGGZ_NONSTRICT
*/
enum OggzFlags {
/** Read only */
......@@ -49,7 +52,15 @@ enum OggzFlags {
/** Disable strict adherence to mapping constraints, eg for
* handling an incomplete stream */
OGGZ_NONSTRICT = 0x10
OGGZ_NONSTRICT = 0x10,
/**
* Scan for known headers while reading, and automatically set
* metrics appropriately. Opening a file for reading with
* \a flags = OGGZ_READ | OGGZ_AUTO will allow seeking on Speex,
* Vorbis, Theora and all Annodex streams in units of milliseconds,
* once all bos pages have been delivered. */
OGGZ_AUTO = 0x20
};
/**
......@@ -88,12 +99,18 @@ enum OggzError {
/** Operation is inappropriate for oggz in current eos state */
OGGZ_ERR_EOS = -6,
/** Operation requires a valid metric, but none has been set */
OGGZ_ERR_BAD_METRIC = -7,
/** System specific error; check errno for details */
OGGZ_ERR_SYSTEM = -10,
/** Functionality disabled at build time */
OGGZ_ERR_DISABLED = -11,
/** Seeking operation is not possible for this OGGZ */
OGGZ_ERR_NOSEEK = -13,
/** The requested serialno does not exist in this OGGZ */
OGGZ_ERR_BAD_SERIALNO = -20,
......
......@@ -17,11 +17,22 @@ if OGGZ_CONFIG_READ
oggz_read_programs = read-file
endif
if OGGZ_CONFIG_WRITE
oggz_write_programs = write-feed write-hungry
endif
# Programs to build
noinst_PROGRAMS = $(oggz_rw_programs) $(oggz_read_programs)
noinst_PROGRAMS = $(oggz_rw_programs) $(oggz_read_programs) \
$(oggz_write_programs)
identity_SOURCES = identity.c
identity_LDADD = $(OGGZ_LIBS)
read_file_SOURCES = read-file.c
read_file_LDADD = $(OGGZ_LIBS)
write_feed_SOURCES = write-feed.c
write_feed_LDADD = $(OGGZ_LIBS)
write_hungry_SOURCES = write-hungry.c
write_hungry_LDADD = $(OGGZ_LIBS)
\ No newline at end of file
......@@ -34,7 +34,8 @@
#include <stdlib.h>
#include <oggz/oggz.h>
static int packetno = 0;
#define ID_WRITE_DIRECT
static int flush_next = 0;
static int
......@@ -44,12 +45,20 @@ read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
int flush;
int ret;
#if 0
flush = flush_next;
if (op->granulepos == -1) {
flush_next = 0;
} else {
flush_next = OGGZ_FLUSH_BEFORE;
}
#else
if (op->granulepos == -1) {
flush = 0;
} else {
flush = OGGZ_FLUSH_AFTER;
}
#endif
if ((ret = oggz_write_feed (writer, op, serialno, flush, NULL)) != 0) {
printf ("oggz_write_feed: %d\n", ret);
......@@ -63,6 +72,8 @@ main (int argc, char ** argv)
{
char * infilename, * outfilename;
OGGZ * reader, * writer;
FILE * outfile;
unsigned char buf[1024];
long n;
if (argc < 3) {
......@@ -77,17 +88,34 @@ main (int argc, char ** argv)
exit (1);
}
#ifdef ID_WRITE_DIRECT
if ((writer = oggz_open (outfilename, OGGZ_WRITE)) == NULL) {
printf ("unable to open file %s\n", outfilename);
exit (1);
}
#else
if ((writer = oggz_new (OGGZ_WRITE)) == NULL) {
printf ("Unable to create new writer\n");
}
outfile = fopen (outfilename, "w");
#endif
oggz_set_read_callback (reader, -1, read_packet, writer);
while ((n = oggz_read (reader, 1024)) > 0) {
#ifdef ID_WRITE_DIRECT
while (oggz_write (writer, n) > 0);
#else
while (oggz_write_output (writer, buf, n) > 0) {
fwrite (buf, 1, n, outfile);
}
#endif
}
#ifndef ID_WRITE_DIRECT
fclose (outfile);
#endif
oggz_close (writer);
oggz_close (reader);
......
......@@ -68,7 +68,7 @@ main (int argc, char ** argv)
printf ("usage: %s filename\n", argv[0]);
}
if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ)) == NULL) {
if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
printf ("unable to open file %s\n", argv[1]);
exit (1);
}
......
......@@ -11,9 +11,10 @@ lib_LTLIBRARIES = liboggz.la
liboggz_la_SOURCES = \
oggz.c \
oggz_private.h \
oggz_private.h oggz_byteorder.h oggz_macros.h \
oggz_read.c oggz_write.c \
oggz_auto.c oggz_auto.h \
oggz_table.c \
oggz_vector.c oggz_vector.h
liboggz_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@
......@@ -10,7 +10,7 @@
global:
oggz_new;
oggz_open;
oggz_openfd;
oggz_open_stdio;
oggz_flush;
oggz_close;
oggz_get_bos;
......@@ -24,11 +24,19 @@
oggz_write_output;
oggz_write_get_next_page_size;
oggz_set_metric;
oggz_set_metric_linear;
oggz_seek_units;
oggz_tell;
oggz_seek;
oggz_data_begins_here;
oggz_set_data_start;
oggz_serialno_new;
oggz_table_new;
oggz_table_delete;
oggz_table_insert;
oggz_table_lookup;
oggz_table_size;
oggz_table_nth;
local:
*;
};
......@@ -46,6 +46,7 @@
#include <ogg/ogg.h>
#include "oggz_private.h"
#include "oggz_vector.h"
/*#define DEBUG*/
......@@ -72,12 +73,12 @@ oggz_new (int flags)
if (oggz == NULL) return NULL;
oggz->flags = flags;
oggz->fd = -1;
oggz->file = NULL;
oggz->offset = 0;
oggz->offset_data_begin = 0;
oggz_vector_init (&oggz->streams, sizeof (oggz_stream_t));
oggz->streams = oggz_vector_new ();
oggz->all_at_eos = 0;
oggz->metric = NULL;
......@@ -100,32 +101,32 @@ OGGZ *
oggz_open (char * filename, int flags)
{
OGGZ * oggz = NULL;
int fd = -1;
FILE * file = NULL;
if (oggz_flags_disabled (flags)) return NULL;
if (flags & OGGZ_WRITE) {
fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
file = fopen (filename, "w");
} else {
fd = open (filename, O_RDONLY);
file = fopen (filename, "r");
}
if (fd == -1) return NULL;
if (file == NULL) return NULL;
oggz = oggz_new (flags);
oggz->fd = fd;
oggz->file = file;
return oggz;
}
OGGZ *
oggz_openfd (int fd, int flags)
oggz_open_stdio (FILE * file, int flags)
{
OGGZ * oggz = NULL;
if (oggz_flags_disabled (flags)) return NULL;
oggz = oggz_new (flags);
oggz->fd = fd;
oggz->file = file;
return oggz;
}
......@@ -135,9 +136,9 @@ oggz_flush (OGGZ * oggz)
{
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (oggz->fd == -1) return OGGZ_ERR_INVALID;
if (oggz->file == NULL) return OGGZ_ERR_INVALID;
if (fsync (oggz->fd) == -1) {
if (fflush (oggz->file) == EOF) {
return OGGZ_ERR_SYSTEM;
}
......@@ -163,8 +164,8 @@ oggz_close (OGGZ * oggz)
{
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
oggz_vector_foreach (&oggz->streams, oggz_stream_clear);
oggz_vector_clear (&oggz->streams);
oggz_vector_foreach (oggz->streams, oggz_stream_clear);
oggz_vector_delete (oggz->streams);
if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) {
oggz_write_close (oggz);
......@@ -172,8 +173,8 @@ oggz_close (OGGZ * oggz)
oggz_read_close (oggz);
}
if (oggz->fd != -1) {
if (close (oggz->fd) == -1) {
if (oggz->file != NULL) {
if (fclose (oggz->file) == EOF) {
return OGGZ_ERR_SYSTEM;
}
}
......@@ -206,7 +207,7 @@ oggz_get_stream (OGGZ * oggz, long serialno)
{
if (serialno < 0) return NULL;
return oggz_vector_find (&oggz->streams, oggz_find_stream, serialno);
return oggz_vector_find (oggz->streams, oggz_find_stream, serialno);
}
oggz_stream_t *
......@@ -233,7 +234,7 @@ oggz_add_stream (OGGZ * oggz, long serialno)
stream->read_packet = NULL;
stream->read_user_data = NULL;
oggz_vector_add_element (&oggz->streams, stream);
oggz_vector_insert_p (oggz->streams, stream);
return stream;
}
......@@ -242,13 +243,14 @@ int
oggz_get_bos (OGGZ * oggz, long serialno)
{
oggz_stream_t * stream;
int i;
int i, size;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (serialno == -1) {
for (i = 0; i < oggz->streams.nr_elements; i++) {
stream = (oggz_stream_t *)oggz->streams.data[i];
size = oggz_vector_size (oggz->streams);
for (i = 0; i < size; i++) {
stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i);
#if 1
/* If this stream has delivered a non bos packet, return FALSE */
if (stream->delivered_non_b_o_s) return 0;
......@@ -271,13 +273,14 @@ int
oggz_get_eos (OGGZ * oggz, long serialno)
{
oggz_stream_t * stream;
int i;
int i, size;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (serialno == -1) {
for (i = 0; i < oggz->streams.nr_elements; i++) {
stream = (oggz_stream_t *)oggz->streams.data[i];
size = oggz_vector_size (oggz->streams);
for (i = 0; i < size; i++) {
stream = (oggz_stream_t *)oggz_vector_nth_p (oggz->streams, i);
if (!stream->e_o_s) return 0;
}
return 1;
......@@ -294,13 +297,14 @@ int
oggz_set_eos (OGGZ * oggz, long serialno)
{
oggz_stream_t * stream;
int i;
int i, size;
if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
if (serialno == -1) {
for (i = 0; i < oggz->streams.nr_elements; i++) {
stream = (oggz_stream_t *)oggz->streams.data[i];
size = oggz_vector_size (oggz->streams);
for (i = 0; i < size; i++) {
stream = (oggz_stream_t *) oggz_vector_nth_p (oggz->streams, i);
stream->e_o_s = 1;
}
oggz->all_at_eos = 1;
......@@ -346,7 +350,7 @@ oggz_metric_default_linear (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
return (ldata->gr_n * granulepos / ldata->gr_d);
}
static int
int
oggz_set_metric_internal (OGGZ * oggz, long serialno,
OggzMetric metric, void * user_data, int internal)
{
......
......@@ -33,24 +33,14 @@
#ifndef __OGGZ_PRIVATE_H__
#define __OGGZ_PRIVATE_H__
#include <stdio.h>
#include <ogg/ogg.h>
#include <oggz/oggz_constants.h>
#include "oggz_macros.h"
#include "oggz_vector.h"
/* Use the malloc and free used by ogg; defaults are those from stdlib */
#define oggz_malloc _ogg_malloc
#define oggz_free _ogg_free
#undef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#undef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#define OGGZ_READ 00
#define OGGZ_WRITE 01
typedef struct _OGGZ OGGZ;
typedef struct _OggzReader OggzReader;
typedef struct _OggzWriter OggzWriter;
......@@ -124,7 +114,7 @@ enum oggz_writer_state {
struct _OggzWriter {
oggz_writer_packet_t * next_zpacket; /* stashed in case of FLUSH_BEFORE */
OggzVector packet_queue;
OggzVector * packet_queue;
OggzWriteHungry hungry;
void * hungry_user_data;
......@@ -151,7 +141,7 @@ struct _OggzWriter {
struct _OGGZ {
int flags;
int fd;
FILE * file;
ogg_packet current_packet;
ogg_page current_page;
......@@ -159,7 +149,7 @@ struct _OGGZ {
off_t offset; /* offset of current page start */
off_t offset_data_begin; /* offset of unit 0 page start */
OggzVector streams;
OggzVector * streams;
int all_at_eos; /* all streams are at eos */
OggzMetric metric;
......@@ -187,4 +177,9 @@ oggz_stream_t * oggz_add_stream (OGGZ * oggz, long serialno);
int oggz_get_bos (OGGZ * oggz, long serialno);
ogg_int64_t oggz_get_unit (OGGZ * oggz, long serialno, ogg_int64_t granulepos);
int oggz_set_metric_internal (OGGZ * oggz, long serialno, OggzMetric metric,
void * user_data, int internal);
int oggz_auto (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data);
#endif /* __OGGZ_PRIVATE_H__ */
This diff is collapsed.
......@@ -34,10 +34,31 @@
#include <stdlib.h>
#include <string.h>
#include "oggz_private.h"
#include "oggz_macros.h"
typedef int (*OggzFunc) (void * data);
typedef int (*OggzFindFunc) (void * data, long serialno);
typedef int (*OggzCmpFunc) (void * a, void * b, void * user_data);
typedef struct _OggzVector OggzVector;
typedef union {
void * p;
long l;
} oggz_data_t;
struct _OggzVector {
int max_elements;
int nr_elements;
oggz_data_t * data;
OggzCmpFunc compare;
void * compare_user_data;
};
/*
* An optionally sorted vector
* A vector of void * or long; iff it's a vector of void * objects, it
* can be optionally sorted. (The sorting is used to implement the
* packet queue; the vector of longs is used to implement OggzTable)
*
* if you set a comparison function (oggz_vector_set_cmp()), the vector
* will be sorted and new elements will be inserted in sorted order.
......@@ -45,22 +66,26 @@
* if you don't set a comparison function, new elements will be appended
* at the tail
*
* to unset the comparison function, call oggz_vector_set_cmp(NULL,NULL)
* to unset the comparison function, call oggz_vector_set_cmp (NULL,NULL)
*/
OggzVector *
oggz_vector_init (OggzVector * vector, size_t sizeof_element)
oggz_vector_new (void)
{
OggzVector * vector;
vector = oggz_malloc (sizeof (OggzVector));
vector->max_elements = 0;
vector->nr_elements = 0;
vector->sizeof_element = sizeof_element;
vector->data = NULL;
vector->compare = NULL;
vector->compare_user_data = NULL;
return vector;
}
void
static void
oggz_vector_clear (OggzVector * vector)
{
oggz_free (vector->data);
......@@ -69,6 +94,41 @@ oggz_vector_clear (OggzVector * vector)
vector->max_elements = 0;
}
void
oggz_vector_delete (OggzVector * vector)
{
oggz_vector_clear (vector);
oggz_free (vector);
}
int
oggz_vector_size (OggzVector * vector)
{
if (vector == NULL) return 0;
return vector->nr_elements;
}
void *
oggz_vector_nth_p (OggzVector * vector, int n)
{
if (vector == NULL) return NULL;
if (n >= vector->nr_elements) return NULL;
return vector->data[n].p;
}
long
oggz_vector_nth_l (OggzVector * vector, int n)
{
if (vector == NULL) return -1L;
if (n >= vector->nr_elements) return -1L;
return vector->data[n].l;
}
void *
oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno)
{
......@@ -76,7 +136,7 @@ oggz_vector_find (OggzVector * vector, OggzFindFunc func, long serialno)
int i;
for (i = 0; i < vector->nr_elements; i++) {
data = vector->data[i];
data = vector->data[i].p;
if (func (data, serialno))
return data;
}
......@@ -90,24 +150,24 @@ oggz_vector_foreach (OggzVector * vector, OggzFunc func)
int i;
for (i = 0; i < vector->nr_elements; i++) {
func (vector->data[i]);
func (vector->data[i].p);
}
return 0;
}
static void
_array_swap (void *v[], int i, int j)
_array_swap (oggz_data_t v[], int i, int j)
{
void * t;
t = v[i];
v[i] = v[j];
v[j] = t;
t = v[i].p;
v[i].p = v[j].p;
v[j].p = t;
}
/**
* Helper function for oggz_vector_element_add(). Sorts the vector by
* Helper function for oggz_vector_insert (). Sorts the vector by