Chris@1: Chris@1: Chris@1:
Chris@1: Chris@1: Chris@1:Libvorbis is the Xiph.Org Foundation's portable Ogg Vorbis CODEC Chris@1: implemented as a programmatic library. Libvorbis provides primitives Chris@1: to handle framing and manipulation of Ogg bitstreams (used by the Chris@1: Vorbis for streaming), a full analysis (encoding) interface as well as Chris@1: packet decoding and synthesis for playback.
Chris@1: Chris@1:The libvorbis library does not provide any system interface; a Chris@1: full-featured demonstration player included with the library Chris@1: distribtion provides example code for a variety of system interfaces Chris@1: as well as a working example of using libvorbis in production code.
Chris@1: Chris@1:Decoding a bitstream with libvorbis follows roughly the following Chris@1: steps:
Chris@1: Chris@1:An Ogg bitstream is logically arranged into pages, but to decode Chris@1: the pages, we have to find them first. The raw bitstream is first fed Chris@1: into an ogg_sync_state buffer using ogg_sync_buffer() Chris@1: and ogg_sync_wrote(). After each block we submit to the sync Chris@1: buffer, we should check to see if we can frame and extract a complete Chris@1: page or pages using ogg_sync_pageout(). Extra pages are Chris@1: buffered; allowing them to build up in the ogg_sync_state Chris@1: buffer will eventually exhaust memory.
Chris@1: Chris@1:The Ogg pages returned from ogg_sync_pageout need not be Chris@1: decoded further to be used as landmarks in seeking; seeking can be Chris@1: either a rough process of simply jumping to approximately intuited Chris@1: portions of the bitstream, or it can be a precise bisection process Chris@1: that captures pages and inspects data position. When seeking, Chris@1: however, sequential multiplexing (chaining) must be accounted for; Chris@1: beginning play in a new logical bitstream requires initializing a Chris@1: synthesis engine with the headers from that bitstream. Vorbis Chris@1: bitstreams do not make use of concurent multiplexing (grouping).
Chris@1: Chris@1:The pages produced by ogg_sync_pageout are then sorted by Chris@1: serial number to seperate logical bitstreams. Initialize logical Chris@1: bitstream buffers (og_stream_state) using Chris@1: ogg_stream_init(). Pages are submitted to the matching Chris@1: logical bitstream buffer using ogg_stream_pagein; the serial Chris@1: number of the page and the stream buffer must match, or the page will Chris@1: be rejected. A page submitted out of sequence will simply be noted, Chris@1: and in the course of outputting packets, the hole will be flagged Chris@1: (ogg_sync_pageout and ogg_stream_packetout will Chris@1: return a negative value at positions where they had to recapture the Chris@1: stream).
Chris@1: Chris@1:After submitting page[s] to a logical stream, read available packets Chris@1: using ogg_stream_packetout.
Chris@1: Chris@1:Two of the Ogg bitstream data structures are intended to be Chris@1: transparent to the developer; the fields should be used directly.
Chris@1: Chris@1:Chris@1: typedef struct { Chris@1: unsigned char *packet; Chris@1: long bytes; Chris@1: long b_o_s; Chris@1: long e_o_s; Chris@1: Chris@1: size64 granulepos; Chris@1: Chris@1: } ogg_packet; Chris@1:Chris@1: Chris@1:
The encoder is responsible for setting all of Chris@1: the fields of the packet to appropriate values before submission to Chris@1: ogg_stream_packetin(); however, it is noted that the value in Chris@1: b_o_s is ignored; the first page produced from a given Chris@1: ogg_stream_state structure will be stamped as the initial Chris@1: page. e_o_s, however, must be set; this is the means by Chris@1: which the stream encoding primitives handle end of stream and cleanup.
Chris@1: Chris@1:ogg_stream_packetout() sets the fields Chris@1: to appropriate values. Note that granulepos will be >= 0 only in the Chris@1: case that the given packet actually represents that position (ie, only Chris@1: the last packet completed on any page will have a meaningful Chris@1: granulepos). Intervening frames will see granulepos set Chris@1: to -1.
Chris@1: Chris@1:Chris@1: typedef struct { Chris@1: unsigned char *header; Chris@1: long header_len; Chris@1: unsigned char *body; Chris@1: long body_len; Chris@1: } ogg_page; Chris@1:Chris@1: Chris@1:
Note that although the header and body pointers do Chris@1: not necessarily point into a single contiguous page vector, the page Chris@1: body must immediately follow the header in the bitstream.
Chris@1: Chris@1:Returns the 'beginning of stream' flag for the given Ogg page. The Chris@1: beginning of stream flag is set on the initial page of a logical Chris@1: bitstream.
Chris@1: Chris@1:Zero indicates the flag is cleared (this is not the initial page of a Chris@1: logical bitstream). Nonzero indicates the flag is set (this is the Chris@1: initial page of a logical bitstream).
Chris@1: Chris@1:Returns the 'packet continued' flag for the given Ogg page. The packet Chris@1: continued flag indicates whether or not the body data of this page Chris@1: begins with packet continued from a preceeding page.
Chris@1: Chris@1:Zero (unset) indicates that the body data begins with a new packet. Chris@1: Nonzero (set) indicates that the first packet data on the page is a Chris@1: continuation from the preceeding page.
Chris@1: Chris@1:Returns the 'end of stream' flag for a give Ogg page. The end of page Chris@1: flag is set on the last (terminal) page of a logical bitstream.
Chris@1: Chris@1:Zero (unset) indicates that this is not the last page of a logical Chris@1: bitstream. Nonzero (set) indicates that this is the last page of a Chris@1: logical bitstream and that no addiitonal pages belonging to this Chris@1: bitstream may follow.
Chris@1: Chris@1:Returns the position of this page as an absolute position within the Chris@1: original uncompressed data. The position, as returned, is 'frames Chris@1: encoded to date up to and including the last whole packet on this Chris@1: page'. Partial packets begun on this page but continued to the Chris@1: following page are not included. If no packet ends on this page, the Chris@1: frame position value will be equal to the frame position value of the Chris@1: preceeding page. If none of the original uncompressed data is yet Chris@1: represented in the logical bitstream (for example, the first page of a Chris@1: bitstream consists only of a header packet; this packet encodes only Chris@1: metadata), the value shall be zero.
Chris@1: Chris@1:The units of the framenumber are determined by media mapping. A Chris@1: vorbis audio bitstream, for example, defines one frame to be the Chris@1: channel values from a single sampling period (eg, a 16 bit stereo Chris@1: bitstream consists of two samples of two bytes for a total of four Chris@1: bytes, thus a frame would be four bytes). A video stream defines one Chris@1: frame to be a single frame of video.
Chris@1: Chris@1:Returns the sequential page number of the given Ogg page. The first Chris@1: page in a logical bitstream is numbered zero; following pages are Chris@1: numbered in increasing monotonic order.
Chris@1: Chris@1:Returns the serial number of the given Ogg page. The serial number is Chris@1: used as a handle to distinguish various logical bitstreams in a Chris@1: physical Ogg bitstresm. Every logical bitstream within a Chris@1: physical bitstream must use a unique (within the scope of the physical Chris@1: bitstream) serial number, which is stamped on all bitstream pages.
Chris@1: Chris@1:Returns the revision of the Ogg bitstream structure of the given page. Chris@1: Currently, the only permitted number is zero. Later revisions of the Chris@1: bitstream spec will increment this version should any changes be Chris@1: incompatable.
Chris@1: Chris@1:Clears and deallocates the internal storage of the given Ogg stream. Chris@1: After clearing, the stream structure is not initialized for use; Chris@1: ogg_stream_init must be called to reinitialize for use. Chris@1: Use ogg_stream_reset to reset the stream state Chris@1: to a fresh, intiialized state.
Chris@1: Chris@1:ogg_stream_clear does not call free() on the pointer Chris@1: os, allowing use of this call on stream structures in static Chris@1: or automatic storage. ogg_stream_destroyis a complimentary Chris@1: function that frees the pointer as well.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:Clears and deallocates the internal storage of the given Ogg stream, Chris@1: then frees the storage associated with the pointer os.
Chris@1: Chris@1:ogg_stream_clear does not call free() on the pointer Chris@1: os, allowing use of that call on stream structures in static Chris@1: or automatic storage.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:Initialize the storage associated with os for use as an Ogg Chris@1: stream. This call is used to initialize a stream for both encode and Chris@1: decode. The given serial number is the serial number that will be Chris@1: stamped on pages of the produced bitstream (during encode), or used as Chris@1: a check that pages match (during decode).
Chris@1: Chris@1:Returns zero on success, nonzero on failure.
Chris@1: Chris@1:Used during encoding to add the given raw packet to the given Ogg Chris@1: bitstream. The contents of op are copied; Chris@1: ogg_stream_packetin does not retain any pointers into Chris@1: op's storage. The encoding proccess buffers incoming packets Chris@1: until enough packets have been assembled to form an entire page; Chris@1: ogg_stream_pageout is used to read complete pages.
Chris@1: Chris@1:Returns zero on success, nonzero on failure.
Chris@1: Chris@1:Used during decoding to read raw packets from the given logical Chris@1: bitstream. ogg_stream_packetout will only return complete Chris@1: packets for which checksumming indicates no corruption. The size and Chris@1: contents of the packet exactly match those given in the encoding Chris@1: process.
Chris@1: Chris@1:Returns zero if the next packet is not ready to be read (not buffered Chris@1: or incomplete), positive if it returned a complete packet in Chris@1: op and negative if there is a gap, extra bytes or corruption Chris@1: at this position in the bitstream (essentially that the bitstream had Chris@1: to be recaptured). A negative value is not necessarily an error. It Chris@1: would be a common occurence when seeking, for example, which requires Chris@1: recapture of the bitstream at the position decoding continued.
Chris@1: Chris@1:If the return value is positive, ogg_stream_packetout placed Chris@1: a packet in op. The data in op points to static Chris@1: storage that is valid until the next call to Chris@1: ogg_stream_pagein, ogg_stream_clear, Chris@1: ogg_stream_reset, or ogg_stream_destroy. The Chris@1: pointers are not invalidated by more calls to Chris@1: ogg_stream_packetout.
Chris@1: Chris@1:Used during decoding to buffer the given complete, pre-verified page Chris@1: for decoding into raw Ogg packets. The given page must be framed, Chris@1: normally produced by ogg_sync_pageout, and from the logical Chris@1: bitstream associated with os (the serial numbers must match). Chris@1: The contents of the given page are copied; ogg_stream_pagein Chris@1: retains no pointers into og storage.
Chris@1: Chris@1:Returns zero on success and non-zero on failure.
Chris@1: Chris@1:Used during encode to read complete pages from the stream buffer. The Chris@1: returned page is ready for sending out to the real world.
Chris@1: Chris@1:Returns zero if there is no complete page ready for reading. Returns Chris@1: nonzero when it has placed data for a complete page into Chris@1: og. Note that the storage returned in og points into internal Chris@1: storage; the pointers in og are valid until the next call to Chris@1: ogg_stream_pageout, ogg_stream_packetin, Chris@1: ogg_stream_reset, ogg_stream_clear or Chris@1: ogg_stream_destroy.
Chris@1: Chris@1:Resets the given stream's state to that of a blank, unused stream; Chris@1: this may be used during encode or decode.
Chris@1: Chris@1:Note that if used during encode, it does not alter the stream's serial Chris@1: number. In addition, the next page produced during encoding will be Chris@1: marked as the 'initial' page of the logical bitstream.
Chris@1: Chris@1:When used during decode, this simply clears the data buffer of any Chris@1: pending pages. Beginning and end of stream cues are read from the Chris@1: bitstream and are unaffected by reset.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:This call is used to buffer a raw bitstream for framing and Chris@1: verification. ogg_sync_buffer handles stream capture and Chris@1: recapture, checksumming, and division into Ogg pages (as required by Chris@1: ogg_stream_pagein).
Chris@1: Chris@1:ogg_sync_buffer exposes a buffer area into which the decoder Chris@1: copies the next (up to) size bytes. We expose the buffer Chris@1: (rather than taking a buffer) in order to avoid an extra copy many Chris@1: uses; this way, for example, read() can transfer data Chris@1: directly into the stream buffer without first needing to place it in Chris@1: temporary storage.
Chris@1: Chris@1:Returns a pointer into oy's internal bitstream sync buffer; Chris@1: the remaining space in the sync buffer is at least size Chris@1: bytes. The decoder need not write all of size bytes; Chris@1: ogg_sync_wrote is used to inform the engine how many bytes Chris@1: were actually written. Use of ogg_sync_wrote after writing Chris@1: into the exposed buffer is mandantory.
Chris@1: Chris@1:ogg_sync_clear Chris@1: clears and deallocates the internal storage of the given Ogg sync Chris@1: buffer. After clearing, the sync structure is not initialized for Chris@1: use; ogg_sync_init must be called to reinitialize for use. Chris@1: Use ogg_sync_reset to reset the sync state and buffer to a Chris@1: fresh, intiialized state.
Chris@1: Chris@1:ogg_sync_clear does not call free() on the pointer Chris@1: oy, allowing use of this call on sync structures in static Chris@1: or automatic storage. ogg_sync_destroyis a complimentary Chris@1: function that frees the pointer as well.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:Clears and deallocates the internal storage of the given Ogg sync Chris@1: buffer, then frees the storage associated with the pointer Chris@1: oy.
Chris@1: Chris@1:An alternative function,ogg_sync_clear, does not call Chris@1: free() on the pointer oy, allowing use of that call on Chris@1: stream structures in static or automatic storage.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:Initializes the sync buffer oy for use.
Chris@1: Chris@1:Returns zero on success and non-zero on failure. This function always Chris@1: succeeds.
Chris@1: Chris@1:Reads complete, framed, verified Ogg pages from the sync buffer, Chris@1: placing the page data in og.
Chris@1: Chris@1:Returns zero when there's no complete pages buffered for Chris@1: retrieval. Returns negative when a loss of sync or recapture occurred Chris@1: (this is not necessarily an error; recapture would be required after Chris@1: seeking, for example). Returns positive when a page is returned in Chris@1: og. Note that the data in og points into the sync Chris@1: buffer storage; the pointers are valid until the next call to Chris@1: ogg_sync_buffer, ogg_sync_clear, Chris@1: ogg_sync_destroy or ogg_sync_reset.
Chris@1: Chris@1:ogg_sync_reset resets the sync state in oy to a Chris@1: clean, empty state. This is useful, for example, when seeking to a Chris@1: new location in a bitstream.
Chris@1: Chris@1:Returns zero on success, nonzero on failure.
Chris@1: Chris@1:Used to inform the sync state as to how many bytes were actually Chris@1: written into the exposed sync buffer. It must be equal to or less Chris@1: than the size of the buffer requested.
Chris@1: Chris@1:Returns zero on success and non-zero on failure; failure occurs only Chris@1: when the number of bytes written were larger than the buffer.
Chris@1: Chris@1: