2017-04-17 06:17:10 -06:00

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_ */