475 lines
19 KiB
C
Executable File
475 lines
19 KiB
C
Executable File
/********************************************************************
|
|
* *
|
|
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
|
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
|
* *
|
|
* THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 *
|
|
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
|
* *
|
|
********************************************************************
|
|
|
|
function:
|
|
last mod: $Id: theora.h,v 1.17 2003/12/06 18:06:19 arc Exp $
|
|
|
|
********************************************************************/
|
|
|
|
#ifndef _O_THEORA_H_
|
|
#define _O_THEORA_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif /* __cplusplus */
|
|
|
|
#ifndef LIBOGG2
|
|
#include <ogg/ogg.h>
|
|
#else
|
|
#include <ogg2/ogg.h>
|
|
/* This is temporary until libogg2 is more complete */
|
|
ogg_buffer_state *ogg_buffer_create(void);
|
|
#endif
|
|
|
|
/** \mainpage
|
|
*
|
|
* \section intro Introduction
|
|
*
|
|
* This is the documentation for the libtheora C API.
|
|
* libtheora is the reference implementation for
|
|
* <a href="http://www.theora.org/">Theora</a>, a free video codec.
|
|
* Theora is derived from On2's VP3 codec with improved integration for
|
|
* Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>.
|
|
*/
|
|
|
|
/** \file
|
|
* The libtheora C API.
|
|
*/
|
|
|
|
/**
|
|
* A YUV buffer for passing uncompressed frames to and from the codec.
|
|
* This holds a Y'CbCr frame in planar format. The CbCr planes can be
|
|
* subsampled and have their own separate dimensions and row stride
|
|
* offsets. Note that the strides may be negative in some
|
|
* configurations. For theora the width and height of the largest plane
|
|
* must be a multiple of 16. The actual meaningful picture size and
|
|
* offset are stored in the theora_info structure; frames returned by
|
|
* the decoder may need to be cropped for display.
|
|
* All samples are 8 bits.
|
|
*/
|
|
typedef struct {
|
|
int y_width; /**< width of the Y' luminance plane */
|
|
int y_height; /**< height of the luminance plane */
|
|
int y_stride; /**< offset in bytes between successive rows */
|
|
|
|
int uv_width; /**< height of the Cb and Cr chroma planes */
|
|
int uv_height; /**< width of the chroma planes */
|
|
int uv_stride; /**< offset between successive chroma rows */
|
|
unsigned char *y; /**< pointer to start of luminance data */
|
|
unsigned char *u; /**< pointer to start of Cb data */
|
|
unsigned char *v; /**< pointer to start of Cr data */
|
|
|
|
} yuv_buffer;
|
|
|
|
/**
|
|
* A Colorspace.
|
|
*/
|
|
typedef enum {
|
|
OC_CS_UNSPECIFIED, /**< the colorspace is unknown or unspecified */
|
|
OC_CS_ITU_REC_470M, /**< best option for 'NTSC' content */
|
|
OC_CS_ITU_REC_470BG, /**< best option for 'PAL' content */
|
|
OC_CS_NSPACES /* mark the end of the defined colorspaces */
|
|
} theora_colorspace;
|
|
|
|
/**
|
|
* A Chroma subsampling
|
|
*
|
|
* These enumerate the available chroma subsampling options supported
|
|
* by the theora format. See Section 4.4 of the specification for
|
|
* exact definitions.
|
|
*/
|
|
typedef enum {
|
|
OC_PF_420, /**< Chroma subsampling by 2 in each direction (4:2:0) */
|
|
OC_PF_RSVD, /**< reserved value */
|
|
OC_PF_422, /**< Horizonatal chroma subsampling by 2 (4:2:2) */
|
|
OC_PF_444, /**< No chroma subsampling at all (4:4:4) */
|
|
} theora_pixelformat;
|
|
|
|
/**
|
|
* Theora bitstream info.
|
|
* Contains the basic playback parameters for a stream,
|
|
* corresponds to the initial 'info' header packet.
|
|
*
|
|
* Encoded theora frames must be a multiple of 16 is size;
|
|
* this is what the width and height members represent. To
|
|
* handle other sizes, a crop rectangle is specified in
|
|
* frame_height and frame_width, offset_x and offset_y. The
|
|
* offset and size should still be a power of 2 to avoid
|
|
* chroma sampling shifts.
|
|
*
|
|
* Frame rate, in frames per second is stored as a rational
|
|
* fraction. So is the aspect ratio. Note that this refers
|
|
* to the aspect ratio of the frame pixels, not of the
|
|
* overall frame itself.
|
|
*
|
|
* see the example code for use of the other parameters and
|
|
* good default settings for the encoder parameters.
|
|
*/
|
|
typedef struct {
|
|
ogg_uint32_t width;
|
|
ogg_uint32_t height;
|
|
ogg_uint32_t frame_width;
|
|
ogg_uint32_t frame_height;
|
|
ogg_uint32_t offset_x;
|
|
ogg_uint32_t offset_y;
|
|
ogg_uint32_t fps_numerator;
|
|
ogg_uint32_t fps_denominator;
|
|
ogg_uint32_t aspect_numerator;
|
|
ogg_uint32_t aspect_denominator;
|
|
theora_colorspace colorspace;
|
|
int target_bitrate;
|
|
int quality; /**< nominal quality setting, 0-63 */
|
|
int quick_p; /**< quick encode/decode */
|
|
|
|
/* decode only */
|
|
unsigned char version_major;
|
|
unsigned char version_minor;
|
|
unsigned char version_subminor;
|
|
|
|
void *codec_setup;
|
|
|
|
/* encode only */
|
|
int dropframes_p;
|
|
int keyframe_auto_p;
|
|
ogg_uint32_t keyframe_frequency;
|
|
ogg_uint32_t keyframe_frequency_force; /* also used for decode init to
|
|
get granpos shift correct */
|
|
ogg_uint32_t keyframe_data_target_bitrate;
|
|
ogg_int32_t keyframe_auto_threshold;
|
|
ogg_uint32_t keyframe_mindistance;
|
|
ogg_int32_t noise_sensitivity;
|
|
ogg_int32_t sharpness;
|
|
|
|
theora_pixelformat pixelformat;
|
|
|
|
} theora_info;
|
|
|
|
/** Codec internal state and context.
|
|
*/
|
|
typedef struct{
|
|
theora_info *i;
|
|
ogg_int64_t granulepos;
|
|
|
|
void *internal_encode;
|
|
void *internal_decode;
|
|
|
|
} theora_state;
|
|
|
|
/**
|
|
* Comment header metadata.
|
|
*
|
|
* This structure holds the in-stream metadata corresponding to
|
|
* the 'comment' header packet.
|
|
*
|
|
* Meta data is stored as a series of (tag, value) pairs, in
|
|
* length-encoded string vectors. The first occurence of the
|
|
* '=' character delimits the tag and value. A particular tag
|
|
* may occur more than once. The character set encoding for
|
|
* the strings is always utf-8, but the tag names are limited
|
|
* to case-insensitive ascii. See the spec for details.
|
|
*
|
|
* In filling in this structure, theora_decode_header() will
|
|
* null-terminate the user_comment strings for safety. However,
|
|
* the bitstream format itself treats them as 8-bit clean,
|
|
* and so the length array should be treated as authoritative
|
|
* for their length.
|
|
*/
|
|
typedef struct theora_comment{
|
|
char **user_comments; /**< an array of comment string vectors */
|
|
int *comment_lengths; /**< an array of corresponding string vector lengths in bytes */
|
|
int comments; /**< the total number of comment string vectors */
|
|
char *vendor; /**< the vendor string identifying the encoder, null terminated */
|
|
|
|
} theora_comment;
|
|
|
|
#define OC_FAULT -1 /**< general failure */
|
|
#define OC_EINVAL -10 /**< library encountered invalid internal data */
|
|
#define OC_DISABLED -11 /**< requested action is disabled */
|
|
#define OC_BADHEADER -20 /**< header packet was corrupt/invalid */
|
|
#define OC_NOTFORMAT -21 /**< packet is not a theora packet */
|
|
#define OC_VERSION -22 /**< bitstream version is not handled */
|
|
#define OC_IMPL -23 /**< feature or action not implemented */
|
|
#define OC_BADPACKET -24 /**< packet is corrupt */
|
|
#define OC_NEWPACKET -25 /**< packet is an (ignorable) unhandled extension */
|
|
|
|
/**
|
|
* Retrieve a human-readable string to identify the encoder vendor and version.
|
|
* \returns a version string.
|
|
*/
|
|
extern const char *theora_version_string(void);
|
|
|
|
/**
|
|
* Retrieve a 32-bit version number.
|
|
* This number is composed of a 16-bit major version, 8-bit minor version
|
|
* and 8 bit sub-version, composed as follows:
|
|
<pre>
|
|
(VERSION_MAJOR<<16) + (VERSION_MINOR<<8) + (VERSION_SUB)
|
|
</pre>
|
|
* \returns the version number.
|
|
*/
|
|
extern ogg_uint32_t theora_version_number(void);
|
|
|
|
/**
|
|
* Initialize the theora encoder.
|
|
* \param th The theora_state handle to initialize for encoding.
|
|
* \param ti A theora_info struct filled with the desired encoding parameters.
|
|
* \returns 0 Success
|
|
*/
|
|
extern int theora_encode_init(theora_state *th, theora_info *c);
|
|
|
|
/**
|
|
* Submit a YUV buffer to the theora encoder.
|
|
* \param t A theora_state handle previously initialized for encoding.
|
|
* \param yuv A buffer of YUV data to encode.
|
|
* \retval OC_EINVAL Encoder is not ready, or is finished.
|
|
* \retval -1 The size of the given frame differs from those previously input
|
|
* \retval 0 Success
|
|
*/
|
|
extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv);
|
|
|
|
/**
|
|
* Request the next packet of encoded video.
|
|
* The encoded data is placed in a user-provided ogg_packet structure.
|
|
* \param t A theora_state handle previously initialized for encoding.
|
|
* \param last_p whether this is the last packet the encoder should produce.
|
|
* \param op An ogg_packet structure to fill. libtheora will set all
|
|
* elements of this structure, including a pointer to encoded
|
|
* data. The memory for the encoded data is owned by libtheora.
|
|
* \retval 0 No internal storage exists OR no packet is ready
|
|
* \retval -1 The encoding process has completed
|
|
* \retval 1 Success
|
|
*/
|
|
extern int theora_encode_packetout( theora_state *t, int last_p,
|
|
ogg_packet *op);
|
|
|
|
/**
|
|
* Request a packet containing the initial header.
|
|
* A pointer to the header data is placed in a user-provided ogg_packet
|
|
* structure.
|
|
* \param t A theora_state handle previously initialized for encoding.
|
|
* \param op An ogg_packet structure to fill. libtheora will set all
|
|
* elements of this structure, including a pointer to the header
|
|
* data. The memory for the header data is owned by libtheora.
|
|
* \retval 0 Success
|
|
*/
|
|
extern int theora_encode_header(theora_state *t, ogg_packet *op);
|
|
|
|
/**
|
|
* Request a comment header packet from provided metadata.
|
|
* A pointer to the comment data is placed in a user-provided ogg_packet
|
|
* structure.
|
|
* \param tc A theora_comment structure filled with the desired metadata
|
|
* \param op An ogg_packet structure to fill. libtheora will set all
|
|
* elements of this structure, including a pointer to the encoded
|
|
* comment data. The memory for the comment data is owned by
|
|
* libtheora.
|
|
* \retval 0 Success
|
|
*/
|
|
extern int theora_encode_comment(theora_comment *tc, ogg_packet *op);
|
|
|
|
/**
|
|
* Request a packet containing the codebook tables for the stream.
|
|
* A pointer to the codebook data is placed in a user-provided ogg_packet
|
|
* structure.
|
|
* \param t A theora_state handle previously initialized for encoding.
|
|
* \param op An ogg_packet structure to fill. libtheora will set all
|
|
* elements of this structure, including a pointer to the codebook
|
|
* data. The memory for the header data is owned by libtheora.
|
|
* \retval 0 Success
|
|
*/
|
|
extern int theora_encode_tables(theora_state *t, ogg_packet *op);
|
|
|
|
/**
|
|
* Decode an Ogg packet, with the expectation that the packet contains
|
|
* an initial header, comment data or codebook tables.
|
|
*
|
|
* \param ci A theora_info structure to fill. This must have been previously
|
|
* initialized with theora_info_init(). If \a op contains an initial
|
|
* header, theora_decode_header() will fill \a ci with the
|
|
* parsed header values. If \a op contains codebook tables,
|
|
* theora_decode_header() will parse these and attach an internal
|
|
* representation to \a ci->codec_setup.
|
|
* \param cc A theora_comment structure to fill. If \a op contains comment
|
|
* data, theora_decode_header() will fill \a cc with the parsed
|
|
* comments.
|
|
* \param op An ogg_packet structure which you expect contains an initial
|
|
* header, comment data or codebook tables.
|
|
*
|
|
* \retval OC_BADHEADER \a op is NULL; OR the first byte of \a op->packet
|
|
* has the signature of an initial packet, but op is
|
|
* not a b_o_s packet; OR this packet has the signature
|
|
* of an initial header packet, but an initial header
|
|
* packet has already been seen; OR this packet has the
|
|
* signature of a comment packet, but the initial header
|
|
* has not yet been seen; OR this packet has the signature
|
|
* of a comment packet, but contains invalid data; OR
|
|
* this packet has the signature of codebook tables,
|
|
* but the initial header or comments have not yet
|
|
* been seen; OR this packet has the signature of codebook
|
|
* tables, but contains invalid data;
|
|
* OR the stream being decoded has a compatible version
|
|
* but this packet does not have the signature of a
|
|
* theora initial header, comments, or codebook packet
|
|
* \retval OC_VERSION The packet data of \a op is an initial header with
|
|
* a version which is incompatible with this version of
|
|
* libtheora.
|
|
* \retval OC_NEWPACKET the stream being decoded has an incompatible (future)
|
|
* version and contains an unknown signature.
|
|
* \retval 0 Success
|
|
*
|
|
* \note The normal usage is that theora_decode_header() be called on the
|
|
* first three packets of a theora logical bitstream in succession.
|
|
*/
|
|
extern int theora_decode_header(theora_info *ci, theora_comment *cc,
|
|
ogg_packet *op);
|
|
|
|
/**
|
|
* Initialize a theora_state handle for decoding.
|
|
* \param th The theora_state handle to initialize.
|
|
* \param c A theora_info struct filled with the desired decoding parameters.
|
|
* This is of course usually obtained from a previous call to
|
|
* theora_decode_header().
|
|
* \returns 0 Success
|
|
*/
|
|
extern int theora_decode_init(theora_state *th, theora_info *c);
|
|
|
|
/**
|
|
* Input a packet containing encoded data into the theora decoder.
|
|
* \param th A theora_state handle previously initialized for decoding.
|
|
* \param op An ogg_packet containing encoded theora data.
|
|
* \retval OC_BADPACKET \a op does not contain encoded video data
|
|
*/
|
|
extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
|
|
|
|
/**
|
|
* Output the next available frame of decoded YUV data.
|
|
* \param th A theora_state handle previously initialized for decoding.
|
|
* \param yuv A yuv_buffer in which libtheora should place the decoded data.
|
|
* \retval 0 Success
|
|
*/
|
|
extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv);
|
|
|
|
/**
|
|
* Report whether a theora packet is a header or not
|
|
* This function does no verification beyond checking the header
|
|
* flag bit so it should not be used for bitstream identification;
|
|
* use theora_decode_header() for that.
|
|
*
|
|
* \param op An ogg_packet containing encoded theora data.
|
|
* \retval 1 The packet is a header packet
|
|
* \retval 0 The packet is not a header packet (and so contains frame data)
|
|
*
|
|
* Thus function was added in the 1.0alpha4 release.
|
|
*/
|
|
extern int theora_packet_isheader(ogg_packet *op);
|
|
|
|
/**
|
|
* Report whether a theora packet is a keyframe or not
|
|
*
|
|
* \param op An ogg_packet containing encoded theora data.
|
|
* \retval 1 The packet contains a keyframe image
|
|
* \retval 0 The packet is contains an interframe delta
|
|
* \retval -1 the packet is not an image data packet at all
|
|
*
|
|
* Thus function was added in the 1.0alpha4 release.
|
|
*/
|
|
extern int theora_packet_iskeyframe(ogg_packet *op);
|
|
|
|
/**
|
|
* Convert a granulepos to an absolute frame number. The granulepos is
|
|
* interpreted in the context of a given theora_state handle.
|
|
*
|
|
* \param th A previously initialized theora_state handle (encode or decode)
|
|
* \param granulepos The granulepos to convert.
|
|
* \returns The frame number corresponding to \a granulepos.
|
|
* \retval -1 The given granulepos is invalid (ie. negative)
|
|
*
|
|
* Thus function was added in the 1.0alpha4 release.
|
|
*/
|
|
extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos);
|
|
|
|
/**
|
|
* Convert a granulepos to absolute time in seconds. The granulepos is
|
|
* interpreted in the context of a given theora_state handle.
|
|
* \param th A previously initialized theora_state handle (encode or decode)
|
|
* \param granulepos The granulepos to convert.
|
|
* \returns The absolute time in seconds corresponding to \a granulepos.
|
|
* \retval -1 The given granulepos is invalid (ie. negative)
|
|
*/
|
|
extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos);
|
|
|
|
/**
|
|
* Initialize a theora_info structure. All values within the given theora_info
|
|
* structure are initialized, and space is allocated within libtheora for
|
|
* internal codec setup data.
|
|
* \param c A theora_info struct to initialize.
|
|
*/
|
|
extern void theora_info_init(theora_info *c);
|
|
|
|
/**
|
|
* Clear a theora_info structure. All values within the given theora_info
|
|
* structure are cleared, and associated internal codec setup data is freed.
|
|
* \param c A theora_info struct to initialize.
|
|
*/
|
|
extern void theora_info_clear(theora_info *c);
|
|
|
|
/**
|
|
* Free all internal data associated with a theora_state handle.
|
|
* \param t A theora_state handle.
|
|
*/
|
|
extern void theora_clear(theora_state *t);
|
|
|
|
/** Initialize an allocated theora_comment structure */
|
|
extern void theora_comment_init(theora_comment *tc);
|
|
/** Add a comment to an initialized theora_comment structure
|
|
\param comment must be a null-terminated string encoding
|
|
the comment in "TAG=the value" form */
|
|
extern void theora_comment_add(theora_comment *tc, char *comment);
|
|
/** Add a comment to an initialized theora_comment structure
|
|
\param tag a null-terminated string containing the tag
|
|
associated with the comment.
|
|
\param value the corresponding value as a null-terminated string
|
|
Neither theora_comment_add() nor theora_comment_add_tag() support
|
|
comments containing null values, although the bitstream format
|
|
supports this. To add such comments you will need to manipulate
|
|
the theora_comment structure directly */
|
|
extern void theora_comment_add_tag(theora_comment *tc,
|
|
char *tag, char *value);
|
|
/** look up a comment value by tag
|
|
\param tc an initialized theora_comment structure
|
|
\param tag the tag to look up
|
|
\param count the instance of the tag. The same tag can appear
|
|
multiple times, each with a distinct and ordered value, so
|
|
an index is required to retrieve them all.
|
|
Use theora_comment_query_count() to get the legal range for the
|
|
count parameter
|
|
\returns a pointer to the queried tag's value
|
|
\retval NULL if no matching tag is found */
|
|
extern char *theora_comment_query(theora_comment *tc, char *tag, int count);
|
|
/** look up the number of instances of a tag
|
|
\param tc an initialized theora_comment structure
|
|
\param tag the tag to look up
|
|
\returns the number on instances of a particular tag.
|
|
Call this first when querying for a specific tag and then interate
|
|
over the number of instances with separate calls to
|
|
theora_comment_query() to retrieve all instances in order. */
|
|
extern int theora_comment_query_count(theora_comment *tc, char *tag);
|
|
/** clears an allocated theora_comment struct so that it can be freed. */
|
|
extern void theora_comment_clear(theora_comment *tc);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* _O_THEORA_H_ */
|