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.
Decoding a bitstream with libvorbis follows roughly the following steps:
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).
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).
After submitting page[s] to a logical stream, read available packets using ogg_stream_packetout.
Two of the Ogg bitstream data structures are intended to be transparent to the developer; the fields should be used directly.
typedef struct { unsigned char *packet; long bytes; long b_o_s; long e_o_s; size64 granulepos; } ogg_packet;
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.
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.
typedef struct { unsigned char *header; long header_len; unsigned char *body; long body_len; } ogg_page;
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Clears and deallocates the internal storage of the given Ogg sync buffer, then frees the storage associated with the pointer oy.
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.
Initializes the sync buffer oy for use.
Returns zero on success and non-zero on failure. This function always succeeds.
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.
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.
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.