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