Commit 7e8bc47d authored by conrad's avatar conrad
Browse files

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 ...@@ -3,24 +3,39 @@ AC_INIT
AC_CONFIG_SRCDIR([src/liboggz/oggz.c]) AC_CONFIG_SRCDIR([src/liboggz/oggz.c])
AC_PREREQ(2.53) AC_PREREQ(2.53)
AC_CONFIG_AUX_DIR(autotools)
AC_CANONICAL_TARGET AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(liboggz, 0.5.43) AM_INIT_AUTOMAKE(liboggz, 0.8.0)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
SHARED_VERSION_INFO="0:5:0" SHARED_VERSION_INFO="1:0:0"
SHLIB_VERSION_ARG="" SHLIB_VERSION_ARG=""
# Checks for programs. # Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_RANLIB
AC_C_CONST AC_C_CONST
AC_C_BIGENDIAN 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 # Check for doxygen
AC_CHECK_PROG(HAVE_DOXYGEN, doxygen, true, false) AC_CHECK_PROG(HAVE_DOXYGEN, doxygen, true, false)
...@@ -30,15 +45,15 @@ if test $HAVE_DOXYGEN = "false"; then ...@@ -30,15 +45,15 @@ if test $HAVE_DOXYGEN = "false"; then
fi fi
# Check for docbook # Check for docbook
AC_CHECK_PROG(HAVE_DOCBOOK, docbook2man, true, false) AC_CHECK_PROG(HAVE_DOCBOOKTOMAN, docbook-to-man, true, false)
AM_CONDITIONAL(HAVE_DOCBOOK,$HAVE_DOCBOOK) AM_CONDITIONAL(HAVE_DOCBOOKTOMAN,$HAVE_DOCBOOKTOMAN)
AC_CHECK_PROG(HAVE_DOCBOOK2HTML, docbook2html, true, false)
dnl Check for types AM_CONDITIONAL(HAVE_DOCBOOK2HTML,$HAVE_DOCBOOK2HTML)
dnl Checks for libraries. dnl Checks for libraries.
LIBS="" LIBS=""
# check for getopt in standard library # check for getopt in a separate library
HAVE_GETOPT=no HAVE_GETOPT=no
AC_CHECK_LIB(getopt, getopt, HAVE_GETOPT="yes") AC_CHECK_LIB(getopt, getopt, HAVE_GETOPT="yes")
if test "x$HAVE_GETOPT" = xyes ; then if test "x$HAVE_GETOPT" = xyes ; then
...@@ -46,6 +61,13 @@ if test "x$HAVE_GETOPT" = xyes ; then ...@@ -46,6 +61,13 @@ if test "x$HAVE_GETOPT" = xyes ; then
AC_SUBST(GETOPT_LIBS) AC_SUBST(GETOPT_LIBS)
fi 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 dnl Overall configuration success flag
oggz_config_ok=yes oggz_config_ok=yes
...@@ -211,6 +233,7 @@ src/Makefile ...@@ -211,6 +233,7 @@ src/Makefile
src/liboggz/Version_script src/liboggz/Version_script
src/liboggz/Makefile src/liboggz/Makefile
src/tools/Makefile src/tools/Makefile
src/tools/oggzdiff
src/tests/Makefile src/tests/Makefile
src/examples/Makefile src/examples/Makefile
oggz.pc oggz.pc
......
...@@ -419,7 +419,7 @@ EXAMPLE_RECURSIVE = NO ...@@ -419,7 +419,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see # directories that contain image that are included in the documentation (see
# the \image command). # the \image command).
IMAGE_PATH = IMAGE_PATH = .
# The INPUT_FILTER tag can be used to specify a program that doxygen should # 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 # invoke to filter for each input file. Doxygen will invoke the filter program
......
docdir=$(prefix)/share/doc/@PACKAGE@ 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 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 doxygen
touch doxygen-build.stamp touch doxygen-build.stamp
else else
...@@ -14,6 +35,23 @@ doxygen-build.stamp: ...@@ -14,6 +35,23 @@ doxygen-build.stamp:
touch doxygen-build.stamp touch doxygen-build.stamp
endif 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 install-data-local: doxygen-build.stamp
$(mkinstalldirs) $(docdir) $(mkinstalldirs) $(docdir)
if test -d liboggz; then \ if test -d liboggz; then \
...@@ -21,7 +59,9 @@ install-data-local: doxygen-build.stamp ...@@ -21,7 +59,9 @@ install-data-local: doxygen-build.stamp
if test -d $$dir; then \ if test -d $$dir; then \
b=`basename $$dir`; \ b=`basename $$dir`; \
$(mkinstalldirs) $(docdir)/$$b; \ $(mkinstalldirs) $(docdir)/$$b; \
(cd $$dir && $(INSTALL_DATA) * $(docdir)/$$b) \ for f in $$dir/*; do \
$(INSTALL_DATA) $$f $(docdir)/$$b; \
done \
fi \ fi \
done \ done \
fi fi
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
# Include files to install # Include files to install
includedir = $(prefix)/include/oggz includedir = $(prefix)/include/oggz
include_HEADERS = oggz.h oggz_constants.h include_HEADERS = oggz.h oggz_constants.h oggz_table.h
...@@ -33,8 +33,11 @@ ...@@ -33,8 +33,11 @@
#ifndef __OGGZ_H__ #ifndef __OGGZ_H__
#define __OGGZ_H__ #define __OGGZ_H__
#include <stdio.h>
#include <ogg/ogg.h> #include <ogg/ogg.h>
#include <oggz/oggz_constants.h> #include <oggz/oggz_constants.h>
#include <oggz/oggz_table.h>
/** \mainpage /** \mainpage
* *
...@@ -46,11 +49,20 @@ ...@@ -46,11 +49,20 @@
* at <a href="http://www.xiph.org/">Xiph.Org</a>, originally to * at <a href="http://www.xiph.org/">Xiph.Org</a>, originally to
* support the Ogg Vorbis audio format. * support the Ogg Vorbis audio format.
* *
* liboggz supports the flexibility afforded by the Ogg file format * liboggz supports the flexibility afforded by the Ogg file format while
* * presenting the following API niceties:
* - A simple, callback based open/read/close or open/write/close interface *
* to all Ogg files * - Strict adherence to the formatting requirements of Ogg
* - A customisable seeking abstraction for seeking on multitrack Ogg data * \link basics bitstreams \endlink, to ensure that only valid bitstreams
* are generated
* - A simple, callback based open/read/close or open/write/close
* \link oggz.h interface \endlink to raw Ogg files
* - A customisable \link seek_api seeking \endlink abstraction for
* seeking on multitrack Ogg data
* - A packet queue for feeding incoming packets for writing, with callback
* based notification when this queue is empty
* - A handy \link oggz_table.h table \endlink structure for storing
* information on each logical bitstream
* *
* \subsection contents Contents * \subsection contents Contents
* *
...@@ -58,7 +70,7 @@ ...@@ -58,7 +70,7 @@
* Information about Ogg required to understand liboggz * Information about Ogg required to understand liboggz
* *
* - \link oggz.h oggz.h \endlink: * - \link oggz.h oggz.h \endlink:
* Documentation of the Oggz API * Documentation of the Oggz C API
* *
* - \link configuration Configuration \endlink: * - \link configuration Configuration \endlink:
* Customizing liboggz to only read or write. * Customizing liboggz to only read or write.
...@@ -88,17 +100,201 @@ ...@@ -88,17 +100,201 @@
* *
* \section Terminology * \section Terminology
* *
* \subsection Bitstreams * The monospace text below is quoted directly from RFC 3533.
* For each concept introduced, tips related to liboggz are provided
* in bullet points.
* *
* Physical bitstreams contain interleaved logical bitstreams. * \subsection bitstreams Physical and Logical Bitstreams
* Each logical bitstream is uniquely identified by a serial number or *
* \a serialno. * The raw data of an Ogg stream, as read directly from a file or network
* socket, is called a <i>physical bitstream</i>.
*
<pre>
The result of an Ogg encapsulation is called the "Physical (Ogg)
Bitstream". It encapsulates one or several encoder-created
bitstreams, which are called "Logical Bitstreams". A logical
bitstream, provided to the Ogg encapsulation process, has a
structure, i.e., it is split up into a sequence of so-called
"Packets". The packets are created by the encoder of that logical
bitstream and represent meaningful entities for that encoder only
(e.g., an uncompressed stream may use video frames as packets).
</pre>
*
* \subsection pages Packets and Pages
*
* Within the Ogg format, packets are written into \a pages. You can think
* of pages like pages in a book, and packets as items of the actual text.
* Consider, for example, individual poems or short stories as the packets.
* Pages are of course all the same size, and a few very short packets could
* be written into a single page. On the other hand, a very long packet will
* use many pages.
* *
* - \a serialno: an integer identifying a logical bitstream. * - liboggz handles the details of writing packets into pages, and of
* reading packets from pages; your application deals only with
* <tt>ogg_packet</tt> structures.
* - Each <tt>ogg_packet</tt> structure contains a block of data and its
* length in bytes, plus other information related to the stream structure
* as explained below.
* *
* \subsection Packets * \subsection serialno
* *
* Each logical bitstream is uniquely identified by a serial number or
* \a serialno.
* *
* - Packets are always associated with a \a serialno. This is not actually
* part of the <tt>ogg_packet</tt> structure, so wherever you see an
* <tt>ogg_packet</tt> in the liboggz API, you will see an accompanying
* \a serialno.
*
<pre>
This unique serial number is created randomly and does not have any
connection to the content or encoder of the logical bitstream it
represents.
</pre>
*
* - Use oggz_serialno_new() to generate a new serial number for each
* logical bitstream you write.
* - Use an \link oggz_table.h OggzTable \endlink, keyed by \a serialno,
* to store and retrieve data related to each logical bitstream.
*
* \subsection boseos b_o_s and e_o_s
<pre>
bos page: The initial page (beginning of stream) of a logical
bitstream which contains information to identify the codec type
and other decoding-relevant information.
eos page: The final page (end of stream) of a logical bitstream.
</pre>
*
* - Every <tt>ogg_packet</tt> contains \a b_o_s and \a e_o_s flags.
* Of course each of these will be set only once per logical bitstream.
* See the Structuring section below for rules on setting \a b_o_s and
* \a e_o_s when interleaving logical bitstreams.
* - This documentation will refer to \a bos and \a eos <i>packets</i>
* (not <i>pages</i>) as that is more closely represented by the API.
* The \a bos packet is the only packet on the \a bos page, and the
* \a eos packet is the last packet on the \a eos page.
*
* \subsection granulepos
<pre>
granule position: An increasing position number for a specific
logical bitstream stored in the page header. Its meaning is
dependent on the codec for that logical bitstream
</pre>
*
* - Every <tt>ogg_packet</tt> contains a \a granulepos. The \a granulepos
* of each packet is used mostly for \link seek_api seeking. \endlink
*
* \section Structuring
*
* The general structure of an Ogg stream is governed by various rules.
*
* \subsection secondaries Secondary header packets
*
* Some data sources require initial setup information such as comments
* and codebooks to be present near the beginning of the stream (directly
* following the b_o_s packets.
*
<pre>
Ogg also allows but does not require secondary header packets after
the bos page for logical bitstreams and these must also precede any
data packets in any logical bitstream. These subsequent header
packets are framed into an integral number of pages, which will not
contain any data packets. So, a physical bitstream begins with the
bos pages of all logical bitstreams containing one initial header
packet per page, followed by the subsidiary header packets of all
streams, followed by pages containing data packets.
</pre>
*
* - liboggz handles the framing of \a packets into low-level \a pages. To
* ensure that the pages used by secondary headers contain no data packets,
* set the \a flush parameter of oggz_write_feed() to \a OGGZ_FLUSH_AFTER
* when queueing the last of the secondary headers.
* - or, equivalently, set \a flush to \a OGGZ_FLUSH_BEFORE when queueing
* the first of the data packets.
*
* \subsection boseosseq Sequencing b_o_s and e_o_s packets
*
* The following rules apply for sequencing \a bos and \a eos packets in
* a physical bitstream:
<pre>
... All bos pages of all logical bitstreams MUST appear together at
the beginning of the Ogg bitstream.
... eos pages for the logical bitstreams need not all occur
contiguously. Eos pages may be 'nil' pages, that is, pages
containing no content but simply a page header with position
information and the eos flag set in the page header.
</pre>
*
* - oggz_write_feed() will fail with a return value of
* \a OGGZ_ERR_BOS if an attempt is made to queue a late \a bos packet
*
* \subsection interleaving Interleaving logical bitstreams
<pre>
It is possible to consecutively chain groups of concurrently
multiplexed bitstreams. The groups, when unchained, MUST stand on
their own as a valid concurrently multiplexed bitstream. The
following diagram shows a schematic example of such a physical
bitstream that obeys all the rules of both grouped and chained
multiplexed bitstreams.
physical bitstream with pages of
different logical bitstreams grouped and chained
-------------------------------------------------------------
|*A*|*B*|*C*|A|A|C|B|A|B|#A#|C|...|B|C|#B#|#C#|*D*|D|...|#D#|
-------------------------------------------------------------
bos bos bos eos eos eos bos eos
In this example, there are two chained physical bitstreams, the first
of which is a grouped stream of three logical bitstreams A, B, and C.
The second physical bitstream is chained after the end of the grouped
bitstream, which ends after the last eos page of all its grouped
logical bitstreams. As can be seen, grouped bitstreams begin
together - all of the bos pages MUST appear before any data pages.
It can also be seen that pages of concurrently multiplexed bitstreams
need not conform to a regular order. And it can be seen that a
grouped bitstream can end long before the other bitstreams in the
group end.
</pre>
*
* - oggz_write_feed() will fail, returning an explicit error value, if
* an attempt is made to queue a packet in violation of these rules.
*
* \section References
*
* This introduction to the Ogg format is derived from
* IETF <a href="http://www.ietf.org/rfc/rfc3533.txt">RFC 3533</a>
* <i>The Ogg File Format version 0</i> in accordance with the
* following copyright statement pertaining to the text of RFC 3533:
*
<pre>
Copyright (C) The Internet Society (2003). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
</pre>
* *
*/ */
...@@ -118,7 +314,7 @@ ...@@ -118,7 +314,7 @@
* *
* Configuring with \a --disable-write will remove all support for writing: * Configuring with \a --disable-write will remove all support for writing:
* - All internal write related functions will not be built * - All internal write related functions will not be built
* - Any attempt to call oggz_new(), oggz_open() or oggz_openfd() * - Any attempt to call oggz_new(), oggz_open() or oggz_open_stdio()
* with \a flags == OGGZ_WRITE will fail, returning NULL * with \a flags == OGGZ_WRITE will fail, returning NULL
* - Any attempt to call oggz_write(), oggz_write_output(), oggz_write_feed(), * - Any attempt to call oggz_write(), oggz_write_output(), oggz_write_feed(),
* oggz_write_set_hungry_callback(), or oggz_write_get_next_page_size() * oggz_write_set_hungry_callback(), or oggz_write_get_next_page_size()
...@@ -128,7 +324,7 @@ ...@@ -128,7 +324,7 @@
* *
* Configuring with \a --disable-read will remove all support for reading: * Configuring with \a --disable-read will remove all support for reading:
* - All internal reading related functions will not be built * - All internal reading related functions will not be built
* - Any attempt to call oggz_new(), oggz_open() or oggz_openfd() * - Any attempt to call oggz_new(), oggz_open() or oggz_open_stdio()
* with \a flags == OGGZ_READ will fail, returning NULL * with \a flags == OGGZ_READ will fail, returning NULL
* - Any attempt to call oggz_read(), oggz_read_input(), * - Any attempt to call oggz_read(), oggz_read_input(),
* oggz_set_read_callback(), oggz_seek(), or oggz_seek_units() will return * oggz_set_read_callback(), oggz_seek(), or oggz_seek_units() will return
...@@ -186,7 +382,7 @@ ...@@ -186,7 +382,7 @@
* in one of three ways: * in one of three ways:
* *
* - oggz_open() - Open a full pathname * - oggz_open() - Open a full pathname
* - oggz_openfd() - Use an already opened file descriptor * - oggz_open_stdio() - Use an already opened FILE
* - oggz_new() - Create an anonymous OGGZ object, which you can later * - oggz_new() - Create an anonymous OGGZ object, which you can later
* handle via memory buffers * handle via memory buffers
* *
...@@ -206,47 +402,24 @@ ...@@ -206,47 +402,24 @@
* callback with oggz_set_write_callback(). * callback with oggz_set_write_callback().
* See the \ref write_api section for details. * See the \ref write_api section for details.
* *
* \section seeking Seeking on Ogg data
*
* To seek while reading Ogg files or streams you must instantiate an OGGZ
* handle for reading, and ensure that an \link metric OggzMetric \endlink
* function is defined to translate packet positions into units such as time.
* See the \ref seek_api section for details.
*
* \section headers Headers * \section headers Headers
* *
* oggz.h provides direct access to libogg types such as ogg_packet, defined * oggz.h provides direct access to libogg types such as ogg_packet, defined
* in <ogg/ogg.h>. * in <ogg/ogg.h>.
*/ */
/** \defgroup seeking_group Seeking
* \section seeking Seeking
*
* The seeking semantics of the Ogg file format were outlined by Monty in
* <a href="http://www.xiph.org/archives/theora-dev/200209/0040.html">a
* post to theora-dev</a> in September 2002. Quoting from that post, we
* have the following assumptions:
*
* - Ogg is not a non-linear format. ... It is a media transport format
* designed to do nothing more than deliver content, in a stream, and
* have all the pieces arrive on time and in sync.
* - The Ogg layer does not know the specifics of the codec data it's
* multiplexing into a stream. It knows nothing beyond 'Oooo, packets!',
* that the packets belong to different buckets, that the packets go in
* order, and that packets have position markers. Ogg does not even have
* a concept of 'time'; it only knows about the sequentially increasing,
* unitless position markers. It is up to higher layers which have
* access to the codec APIs to assign and convert units of framing or
* time.
*
* liboggz provides two abstractions for seeking at an arbitrary level of
* precision, as well as allowing seeking to a direct byte offset.
*
* To seek across non-metric spaces for which a partial order
* exists (ie. data that is not synchronised by a measure such as time, but
* is nevertheless somehow seekably structured), use an OggzOrder.
*
* For most purposes, such as media data, use an OggzMetric instead.
*/
/** /**
* An opaque handle to an Ogg file. This is returned by oggz_open() or * An opaque handle to an Ogg file. This is returned by oggz_open() or
* oggz_new(), and is passed to all other oggz_* functions. * oggz_new(), and is passed to all other oggz_* functions.
*/ */
typedef void * OGGZ; typedef void OGGZ;
/** /**
* Create a new OGGZ object * Create a new OGGZ object
...@@ -266,16 +439,16 @@ OGGZ * oggz_new (int flags); ...@@ -266,16 +439,16 @@ OGGZ * oggz_new (int flags);
OGGZ * oggz_open (char * filename, int flags); OGGZ * oggz_open (char * filename, int flags);
/** /**
* Create an OGGZ handle associated with a file descriptor. * Create an OGGZ handle associated with a stdio stream
* \param fd An open file descriptor * \param file An open FILE handle
* \param flags OGGZ_READ or OGGZ_WRITE * \param flags OGGZ_READ or OGGZ_WRITE
* \returns A new OGGZ handle * \returns A new OGGZ handle
* \retval NULL System error; check errno for details * \retval NULL System error; check errno for details
*/ */
OGGZ * oggz_openfd (int fd, int flags); OGGZ * oggz_open_stdio (FILE * file, int flags);
/** /**
* Ensure any associated file descriptors are flushed. * Ensure any associated stdio streams are flushed.
* \param oggz An OGGZ handle * \param oggz An OGGZ handle
* \retval 0 Success * \retval 0 Success
* \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
...@@ -318,6 +491,17 @@ int oggz_get_bos (OGGZ * oggz, long serialno); ...@@ -318,6 +491,17 @@ int oggz_get_bos (OGGZ * oggz, long serialno);
int oggz_get_eos (OGGZ * oggz, long serialno); int oggz_get_eos (OGGZ * oggz, long serialno);