From 74f4b1bc3b627ba4c7e03498234d88cacdfbe97b Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 29 Sep 2021 22:52:49 +0200 Subject: Squashed 'vorbis/' content from commit d22c3ab5f git-subtree-dir: vorbis git-subtree-split: d22c3ab5f633460abc2532feee60ca0892134cbf --- doc/programming.html | 554 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 554 insertions(+) create mode 100644 doc/programming.html (limited to 'doc/programming.html') diff --git a/doc/programming.html b/doc/programming.html new file mode 100644 index 0000000..4b54347 --- /dev/null +++ b/doc/programming.html @@ -0,0 +1,554 @@ + + + + + +Ogg Vorbis Documentation + + + + + + + + + +

Programming with Xiph.Org libvorbis

+ +

Description

+ +

Libvorbis is the Xiph.Org Foundation's portable Ogg Vorbis CODEC +implemented as a programmatic library. Libvorbis provides primitives +to handle framing and manipulation of Ogg bitstreams (used by the +Vorbis for streaming), a full analysis (encoding) interface as well as +packet decoding and synthesis for playback.

+ +

The libvorbis library does not provide any system interface; a +full-featured demonstration player included with the library +distribtion provides example code for a variety of system interfaces +as well as a working example of using libvorbis in production code.

+ +

Encoding Overview

+ +

Decoding Overview

+ +

Decoding a bitstream with libvorbis follows roughly the following +steps:

+ +
    +
  1. Frame the incoming bitstream into pages
  2. +
  3. Sort the pages by logical bitstream and buffer then into logical streams
  4. +
  5. Decompose the logical streams into raw packets
  6. +
  7. Reconstruct segments of the original data from each packet
  8. +
  9. Glue the reconstructed segments back into a decoded stream
  10. +
+ +

Framing

+ +

An Ogg bitstream is logically arranged into pages, but to decode +the pages, we have to find them first. The raw bitstream is first fed +into an ogg_sync_state buffer using ogg_sync_buffer() +and ogg_sync_wrote(). After each block we submit to the sync +buffer, we should check to see if we can frame and extract a complete +page or pages using ogg_sync_pageout(). Extra pages are +buffered; allowing them to build up in the ogg_sync_state +buffer will eventually exhaust memory.

+ +

The Ogg pages returned from ogg_sync_pageout need not be +decoded further to be used as landmarks in seeking; seeking can be +either a rough process of simply jumping to approximately intuited +portions of the bitstream, or it can be a precise bisection process +that captures pages and inspects data position. When seeking, +however, sequential multiplexing (chaining) must be accounted for; +beginning play in a new logical bitstream requires initializing a +synthesis engine with the headers from that bitstream. Vorbis +bitstreams do not make use of concurent multiplexing (grouping).

+ +

Sorting

+ +

The pages produced by ogg_sync_pageout are then sorted by +serial number to seperate logical bitstreams. Initialize logical +bitstream buffers (og_stream_state) using +ogg_stream_init(). Pages are submitted to the matching +logical bitstream buffer using ogg_stream_pagein; the serial +number of the page and the stream buffer must match, or the page will +be rejected. A page submitted out of sequence will simply be noted, +and in the course of outputting packets, the hole will be flagged +(ogg_sync_pageout and ogg_stream_packetout will +return a negative value at positions where they had to recapture the +stream).

+ +

Extracting packets

+ +

After submitting page[s] to a logical stream, read available packets +using ogg_stream_packetout.

+ +

Decoding packets

+ +

Reassembling data segments

+ +

Ogg Bitstream Manipulation Structures

+ +

Two of the Ogg bitstream data structures are intended to be +transparent to the developer; the fields should be used directly.

+ +

ogg_packet

+ +
+typedef struct {
+  unsigned char *packet;
+  long  bytes;
+  long  b_o_s;
+  long  e_o_s;
+
+  size64 granulepos;
+
+} ogg_packet;
+
+ +
+
packet:
+
a pointer to the byte data of the raw packet
+
bytes:
+
the size of the packet' raw data
+
b_o_s:
+
beginning of stream; nonzero if this is the first packet of + the logical bitstream
+
e_o_s:
+
end of stream; nonzero if this is the last packet of the + logical bitstream
+
granulepos:
+
the absolute position of this packet in the original + uncompressed data stream.
+
+ +

encoding notes

+ +

The encoder is responsible for setting all of +the fields of the packet to appropriate values before submission to +ogg_stream_packetin(); however, it is noted that the value in +b_o_s is ignored; the first page produced from a given +ogg_stream_state structure will be stamped as the initial +page. e_o_s, however, must be set; this is the means by +which the stream encoding primitives handle end of stream and cleanup.

+ +

decoding notes

+ +

ogg_stream_packetout() sets the fields +to appropriate values. Note that granulepos will be >= 0 only in the +case that the given packet actually represents that position (ie, only +the last packet completed on any page will have a meaningful +granulepos). Intervening frames will see granulepos set +to -1.

+ +

ogg_page

+ +
+typedef struct {
+  unsigned char *header;
+  long header_len;
+  unsigned char *body;
+  long body_len;
+} ogg_page;
+
+ +
+
header:
+
pointer to the page header data
+
header_len:
+
length of the page header in bytes
+
body:
+
pointer to the page body
+
body_len:
+
length of the page body
+
+ +

Note that although the header and body pointers do +not necessarily point into a single contiguous page vector, the page +body must immediately follow the header in the bitstream.

+ +

Ogg Bitstream Manipulation Functions

+ +

+int ogg_page_bos(ogg_page *og); +

+ +

Returns the 'beginning of stream' flag for the given Ogg page. The +beginning of stream flag is set on the initial page of a logical +bitstream.

+ +

Zero indicates the flag is cleared (this is not the initial page of a +logical bitstream). Nonzero indicates the flag is set (this is the +initial page of a logical bitstream).

+ +

+int ogg_page_continued(ogg_page *og); +

+ +

Returns the 'packet continued' flag for the given Ogg page. The packet +continued flag indicates whether or not the body data of this page +begins with packet continued from a preceeding page.

+ +

Zero (unset) indicates that the body data begins with a new packet. +Nonzero (set) indicates that the first packet data on the page is a +continuation from the preceeding page.

+ +

+int ogg_page_eos(ogg_page *og); +

+ +

Returns the 'end of stream' flag for a give Ogg page. The end of page +flag is set on the last (terminal) page of a logical bitstream.

+ +

Zero (unset) indicates that this is not the last page of a logical +bitstream. Nonzero (set) indicates that this is the last page of a +logical bitstream and that no addiitonal pages belonging to this +bitstream may follow.

+ +

+size64 ogg_page_granulepos(ogg_page *og); +

+ +

Returns the position of this page as an absolute position within the +original uncompressed data. The position, as returned, is 'frames +encoded to date up to and including the last whole packet on this +page'. Partial packets begun on this page but continued to the +following page are not included. If no packet ends on this page, the +frame position value will be equal to the frame position value of the +preceeding page. If none of the original uncompressed data is yet +represented in the logical bitstream (for example, the first page of a +bitstream consists only of a header packet; this packet encodes only +metadata), the value shall be zero.

+ +

The units of the framenumber are determined by media mapping. A +vorbis audio bitstream, for example, defines one frame to be the +channel values from a single sampling period (eg, a 16 bit stereo +bitstream consists of two samples of two bytes for a total of four +bytes, thus a frame would be four bytes). A video stream defines one +frame to be a single frame of video.

+ +

+int ogg_page_pageno(ogg_page *og); +

+ +

Returns the sequential page number of the given Ogg page. The first +page in a logical bitstream is numbered zero; following pages are +numbered in increasing monotonic order.

+ +

+int ogg_page_serialno(ogg_page *og); +

+ +

Returns the serial number of the given Ogg page. The serial number is +used as a handle to distinguish various logical bitstreams in a +physical Ogg bitstresm. Every logical bitstream within a +physical bitstream must use a unique (within the scope of the physical +bitstream) serial number, which is stamped on all bitstream pages.

+ +

+int ogg_page_version(ogg_page *og); +

+ +

Returns the revision of the Ogg bitstream structure of the given page. +Currently, the only permitted number is zero. Later revisions of the +bitstream spec will increment this version should any changes be +incompatable.

+ +

+int ogg_stream_clear(ogg_stream_state *os); +

+ +

Clears and deallocates the internal storage of the given Ogg stream. +After clearing, the stream structure is not initialized for use; +ogg_stream_init must be called to reinitialize for use. +Use ogg_stream_reset to reset the stream state +to a fresh, intiialized state.

+ +

ogg_stream_clear does not call free() on the pointer +os, allowing use of this call on stream structures in static +or automatic storage. ogg_stream_destroyis a complimentary +function that frees the pointer as well.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+int ogg_stream_destroy(ogg_stream_state *os); +

+ +

Clears and deallocates the internal storage of the given Ogg stream, +then frees the storage associated with the pointer os.

+ +

ogg_stream_clear does not call free() on the pointer +os, allowing use of that call on stream structures in static +or automatic storage.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+int ogg_stream_init(ogg_stream_state *os,int serialno); +

+ +

Initialize the storage associated with os for use as an Ogg +stream. This call is used to initialize a stream for both encode and +decode. The given serial number is the serial number that will be +stamped on pages of the produced bitstream (during encode), or used as +a check that pages match (during decode).

+ +

Returns zero on success, nonzero on failure.

+ +

+int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +

+ +

Used during encoding to add the given raw packet to the given Ogg +bitstream. The contents of op are copied; +ogg_stream_packetin does not retain any pointers into +op's storage. The encoding proccess buffers incoming packets +until enough packets have been assembled to form an entire page; +ogg_stream_pageout is used to read complete pages.

+ +

Returns zero on success, nonzero on failure.

+ +

+int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +

+ +

Used during decoding to read raw packets from the given logical +bitstream. ogg_stream_packetout will only return complete +packets for which checksumming indicates no corruption. The size and +contents of the packet exactly match those given in the encoding +process.

+ +

Returns zero if the next packet is not ready to be read (not buffered +or incomplete), positive if it returned a complete packet in +op and negative if there is a gap, extra bytes or corruption +at this position in the bitstream (essentially that the bitstream had +to be recaptured). A negative value is not necessarily an error. It +would be a common occurence when seeking, for example, which requires +recapture of the bitstream at the position decoding continued.

+ +

If the return value is positive, ogg_stream_packetout placed +a packet in op. The data in op points to static +storage that is valid until the next call to +ogg_stream_pagein, ogg_stream_clear, +ogg_stream_reset, or ogg_stream_destroy. The +pointers are not invalidated by more calls to +ogg_stream_packetout.

+ +

+int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +

+ +

Used during decoding to buffer the given complete, pre-verified page +for decoding into raw Ogg packets. The given page must be framed, +normally produced by ogg_sync_pageout, and from the logical +bitstream associated with os (the serial numbers must match). +The contents of the given page are copied; ogg_stream_pagein +retains no pointers into og storage.

+ +

Returns zero on success and non-zero on failure.

+ +

+int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +

+ +

Used during encode to read complete pages from the stream buffer. The +returned page is ready for sending out to the real world.

+ +

Returns zero if there is no complete page ready for reading. Returns +nonzero when it has placed data for a complete page into +og. Note that the storage returned in og points into internal +storage; the pointers in og are valid until the next call to +ogg_stream_pageout, ogg_stream_packetin, +ogg_stream_reset, ogg_stream_clear or +ogg_stream_destroy.

+ +

+int ogg_stream_reset(ogg_stream_state *os); +

+ +

Resets the given stream's state to that of a blank, unused stream; +this may be used during encode or decode.

+ +

Note that if used during encode, it does not alter the stream's serial +number. In addition, the next page produced during encoding will be +marked as the 'initial' page of the logical bitstream.

+ +

When used during decode, this simply clears the data buffer of any +pending pages. Beginning and end of stream cues are read from the +bitstream and are unaffected by reset.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+char *ogg_sync_buffer(ogg_sync_state *oy, long size); +

+ +

This call is used to buffer a raw bitstream for framing and +verification. ogg_sync_buffer handles stream capture and +recapture, checksumming, and division into Ogg pages (as required by +ogg_stream_pagein).

+ +

ogg_sync_buffer exposes a buffer area into which the decoder +copies the next (up to) size bytes. We expose the buffer +(rather than taking a buffer) in order to avoid an extra copy many +uses; this way, for example, read() can transfer data +directly into the stream buffer without first needing to place it in +temporary storage.

+ +

Returns a pointer into oy's internal bitstream sync buffer; +the remaining space in the sync buffer is at least size +bytes. The decoder need not write all of size bytes; +ogg_sync_wrote is used to inform the engine how many bytes +were actually written. Use of ogg_sync_wrote after writing +into the exposed buffer is mandantory.

+ +

+int ogg_sync_clear(ogg_sync_state *oy); +

+ +

ogg_sync_clear +clears and deallocates the internal storage of the given Ogg sync +buffer. After clearing, the sync structure is not initialized for +use; ogg_sync_init must be called to reinitialize for use. +Use ogg_sync_reset to reset the sync state and buffer to a +fresh, intiialized state.

+ +

ogg_sync_clear does not call free() on the pointer +oy, allowing use of this call on sync structures in static +or automatic storage. ogg_sync_destroyis a complimentary +function that frees the pointer as well.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+int ogg_sync_destroy(ogg_sync_state *oy); +

+ +

Clears and deallocates the internal storage of the given Ogg sync +buffer, then frees the storage associated with the pointer +oy.

+ +

An alternative function,ogg_sync_clear, does not call +free() on the pointer oy, allowing use of that call on +stream structures in static or automatic storage.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+int ogg_sync_init(ogg_sync_state *oy); +

+ +

Initializes the sync buffer oy for use.

+ +

Returns zero on success and non-zero on failure. This function always +succeeds.

+ +

+int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +

+ +

Reads complete, framed, verified Ogg pages from the sync buffer, +placing the page data in og.

+ +

Returns zero when there's no complete pages buffered for +retrieval. Returns negative when a loss of sync or recapture occurred +(this is not necessarily an error; recapture would be required after +seeking, for example). Returns positive when a page is returned in +og. Note that the data in og points into the sync +buffer storage; the pointers are valid until the next call to +ogg_sync_buffer, ogg_sync_clear, +ogg_sync_destroy or ogg_sync_reset.

+ +

+int ogg_sync_reset(ogg_sync_state *oy); +

+ +

ogg_sync_reset resets the sync state in oy to a +clean, empty state. This is useful, for example, when seeking to a +new location in a bitstream.

+ +

Returns zero on success, nonzero on failure.

+ +

+int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +

+ +

Used to inform the sync state as to how many bytes were actually +written into the exposed sync buffer. It must be equal to or less +than the size of the buffer requested.

+ +

Returns zero on success and non-zero on failure; failure occurs only +when the number of bytes written were larger than the buffer.

+ + + + + -- cgit v1.1